// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

@TestOn('mac-os')
library;

import '../../../packages/flutter_tools/test/src/fake_process_manager.dart';
import '../suite_runners/run_verify_binaries_codesigned_tests.dart';
import './common.dart';

void main() async {
  const flutterRoot = '/a/b/c';
  final List<String> allExpectedFiles =
      binariesWithEntitlements(flutterRoot) + binariesWithoutEntitlements(flutterRoot);
  final String allFilesStdout = allExpectedFiles.join('\n');
  final List<String> allExpectedXcframeworks = signedXcframeworks(flutterRoot);
  final String allXcframeworksStdout = allExpectedXcframeworks.join('\n');
  final List<String> withEntitlements = binariesWithEntitlements(flutterRoot);

  group('verifyExist', () {
    test('Not all files found', () async {
      final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['find', '/a/b/c/bin/cache', '-type', 'f'],
          stdout: '/a/b/c/bin/cache/artifacts/engine/android-arm-profile/darwin-x64/gen_snapshot',
        ),
        const FakeCommand(
          command: <String>[
            'file',
            '--mime-type',
            '-b',
            '/a/b/c/bin/cache/artifacts/engine/android-arm-profile/darwin-x64/gen_snapshot',
          ],
          stdout: 'application/x-mach-binary',
        ),
      ]);
      expect(
        () async => verifyExist(flutterRoot, processManager: processManager),
        throwsExceptionWith('Did not find all expected binaries!'),
      );
    });

    test('All files found', () async {
      final commandList = <FakeCommand>[];
      final findCmd = FakeCommand(
        command: const <String>['find', '$flutterRoot/bin/cache', '-type', 'f'],
        stdout: allFilesStdout,
      );
      commandList.add(findCmd);
      for (final expectedFile in allExpectedFiles) {
        commandList.add(
          FakeCommand(
            command: <String>['file', '--mime-type', '-b', expectedFile],
            stdout: 'application/x-mach-binary',
          ),
        );
      }
      final ProcessManager processManager = FakeProcessManager.list(commandList);
      await expectLater(verifyExist('/a/b/c', processManager: processManager), completes);
    });
  });

  group('find paths', () {
    test('All binary files found', () async {
      final commandList = <FakeCommand>[];
      final findCmd = FakeCommand(
        command: const <String>['find', '$flutterRoot/bin/cache', '-type', 'f'],
        stdout: allFilesStdout,
      );
      commandList.add(findCmd);
      for (final expectedFile in allExpectedFiles) {
        commandList.add(
          FakeCommand(
            command: <String>['file', '--mime-type', '-b', expectedFile],
            stdout: 'application/x-mach-binary',
          ),
        );
      }
      final ProcessManager processManager = FakeProcessManager.list(commandList);
      final List<String> foundFiles = await findBinaryPaths(
        '$flutterRoot/bin/cache',
        processManager: processManager,
      );
      expect(foundFiles, allExpectedFiles);
    });

    test('Empty file list', () async {
      final commandList = <FakeCommand>[];
      const findCmd = FakeCommand(
        command: <String>['find', '$flutterRoot/bin/cache', '-type', 'f'],
      );
      commandList.add(findCmd);
      final ProcessManager processManager = FakeProcessManager.list(commandList);
      final List<String> foundFiles = await findBinaryPaths(
        '$flutterRoot/bin/cache',
        processManager: processManager,
      );
      expect(foundFiles, <String>[]);
    });

    test('All xcframeworks files found', () async {
      final commandList = <FakeCommand>[
        FakeCommand(
          command: const <String>[
            'find',
            '$flutterRoot/bin/cache',
            '-type',
            'd',
            '-name',
            '*xcframework',
          ],
          stdout: allXcframeworksStdout,
        ),
      ];
      final ProcessManager processManager = FakeProcessManager.list(commandList);
      final List<String> foundFiles = await findXcframeworksPaths(
        '$flutterRoot/bin/cache',
        processManager: processManager,
      );
      expect(foundFiles, allExpectedXcframeworks);
    });

    group('isBinary', () {
      test('isTrue', () async {
        final commandList = <FakeCommand>[];
        const fileToCheck = '/a/b/c/one.zip';
        const findCmd = FakeCommand(
          command: <String>['file', '--mime-type', '-b', fileToCheck],
          stdout: 'application/x-mach-binary',
        );
        commandList.add(findCmd);
        final ProcessManager processManager = FakeProcessManager.list(commandList);
        final bool result = await isBinary(fileToCheck, processManager: processManager);
        expect(result, isTrue);
      });

      test('isFalse', () async {
        final commandList = <FakeCommand>[];
        const fileToCheck = '/a/b/c/one.zip';
        const findCmd = FakeCommand(
          command: <String>['file', '--mime-type', '-b', fileToCheck],
          stdout: 'text/xml',
        );
        commandList.add(findCmd);
        final ProcessManager processManager = FakeProcessManager.list(commandList);
        final bool result = await isBinary(fileToCheck, processManager: processManager);
        expect(result, isFalse);
      });
    });

    group('hasExpectedEntitlements', () {
      test('expected entitlements', () async {
        final commandList = <FakeCommand>[];
        const fileToCheck = '/a/b/c/one.zip';
        const codesignCmd = FakeCommand(
          command: <String>['codesign', '--display', '--entitlements', ':-', fileToCheck],
        );
        commandList.add(codesignCmd);
        final ProcessManager processManager = FakeProcessManager.list(commandList);
        final bool result = await hasExpectedEntitlements(
          fileToCheck,
          flutterRoot,
          processManager: processManager,
        );
        expect(result, isTrue);
      });

      test('unexpected entitlements', () async {
        final commandList = <FakeCommand>[];
        const fileToCheck = '/a/b/c/one.zip';
        const codesignCmd = FakeCommand(
          command: <String>['codesign', '--display', '--entitlements', ':-', fileToCheck],
          exitCode: 1,
        );
        commandList.add(codesignCmd);
        final ProcessManager processManager = FakeProcessManager.list(commandList);
        final bool result = await hasExpectedEntitlements(
          fileToCheck,
          flutterRoot,
          processManager: processManager,
        );
        expect(result, isFalse);
      });
    });
  });

  group('verifySignatures', () {
    test('succeeds if every binary is codesigned and has correct entitlements', () async {
      final commandList = <FakeCommand>[];
      final findCmd = FakeCommand(
        command: const <String>['find', '$flutterRoot/bin/cache', '-type', 'f'],
        stdout: allFilesStdout,
      );
      commandList.add(findCmd);
      for (final expectedFile in allExpectedFiles) {
        commandList.add(
          FakeCommand(
            command: <String>['file', '--mime-type', '-b', expectedFile],
            stdout: 'application/x-mach-binary',
          ),
        );
      }
      commandList.add(
        FakeCommand(
          command: const <String>[
            'find',
            '$flutterRoot/bin/cache',
            '-type',
            'd',
            '-name',
            '*xcframework',
          ],
          stdout: allXcframeworksStdout,
        ),
      );
      for (final expectedFile in allExpectedFiles) {
        commandList.add(FakeCommand(command: <String>['codesign', '-vvv', expectedFile]));
        if (withEntitlements.contains(expectedFile)) {
          commandList.add(
            FakeCommand(
              command: <String>['codesign', '--display', '--entitlements', ':-', expectedFile],
              stdout: expectedEntitlements.join('\n'),
            ),
          );
        }
      }

      for (final expectedXcframework in allExpectedXcframeworks) {
        commandList.add(FakeCommand(command: <String>['codesign', '-vvv', expectedXcframework]));
      }
      final ProcessManager processManager = FakeProcessManager.list(commandList);
      await expectLater(verifySignatures(flutterRoot, processManager: processManager), completes);
    });

    test('fails if binaries do not have the right entitlements', () async {
      final commandList = <FakeCommand>[];
      final findCmd = FakeCommand(
        command: const <String>['find', '$flutterRoot/bin/cache', '-type', 'f'],
        stdout: allFilesStdout,
      );
      commandList.add(findCmd);
      for (final expectedFile in allExpectedFiles) {
        commandList.add(
          FakeCommand(
            command: <String>['file', '--mime-type', '-b', expectedFile],
            stdout: 'application/x-mach-binary',
          ),
        );
      }
      commandList.add(
        FakeCommand(
          command: const <String>[
            'find',
            '$flutterRoot/bin/cache',
            '-type',
            'd',
            '-name',
            '*xcframework',
          ],
          stdout: allXcframeworksStdout,
        ),
      );
      for (final expectedFile in allExpectedFiles) {
        commandList.add(FakeCommand(command: <String>['codesign', '-vvv', expectedFile]));
        if (withEntitlements.contains(expectedFile)) {
          commandList.add(
            FakeCommand(
              command: <String>['codesign', '--display', '--entitlements', ':-', expectedFile],
            ),
          );
        }
      }
      for (final expectedXcframework in allExpectedXcframeworks) {
        commandList.add(FakeCommand(command: <String>['codesign', '-vvv', expectedXcframework]));
      }
      final ProcessManager processManager = FakeProcessManager.list(commandList);

      expect(
        () async => verifySignatures(flutterRoot, processManager: processManager),
        throwsExceptionWith('Test failed because files found with the wrong entitlements'),
      );
    });
  });
}
