// 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 '../test.dart';
import './common.dart';

void main() async {
  const String 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 List<FakeCommand> commandList = <FakeCommand>[];
      final FakeCommand findCmd = FakeCommand(
        command: const <String>[
          'find',
          '$flutterRoot/bin/cache',
          '-type',
          'f',],
        stdout: allFilesStdout,
          );
      commandList.add(findCmd);
      for (final String 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 List<FakeCommand> commandList = <FakeCommand>[];
      final FakeCommand findCmd = FakeCommand(
        command: const <String>[
          'find',
          '$flutterRoot/bin/cache',
          '-type',
          'f',],
        stdout: allFilesStdout,
      );
      commandList.add(findCmd);
      for (final String 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 List<FakeCommand> commandList = <FakeCommand>[];
      const FakeCommand 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 List<FakeCommand> 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 List<FakeCommand> commandList = <FakeCommand>[];
      const String fileToCheck = '/a/b/c/one.zip';
      const FakeCommand 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 List<FakeCommand> commandList = <FakeCommand>[];
      const String fileToCheck = '/a/b/c/one.zip';
      const FakeCommand 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 List<FakeCommand> commandList = <FakeCommand>[];
       const String fileToCheck = '/a/b/c/one.zip';
       const FakeCommand 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 List<FakeCommand> commandList = <FakeCommand>[];
       const String fileToCheck = '/a/b/c/one.zip';
       const FakeCommand 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 List<FakeCommand> commandList = <FakeCommand>[];
      final FakeCommand findCmd = FakeCommand(
        command: const <String>[
          'find',
          '$flutterRoot/bin/cache',
          '-type',
          'f',],
        stdout: allFilesStdout,
          );
      commandList.add(findCmd);
      for (final String 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 String 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 String 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 List<FakeCommand> commandList = <FakeCommand>[];
      final FakeCommand findCmd = FakeCommand(
        command: const <String>[
          'find',
          '$flutterRoot/bin/cache',
          '-type',
          'f',],
        stdout: allFilesStdout,
          );
      commandList.add(findCmd);
      for (final String 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 String 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 String 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'),
      );
    });
  });
}
