// 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.

import 'dart:io' as io;

import 'package:args/command_runner.dart';
import 'package:file/file.dart';
import 'package:meta/meta.dart' show visibleForTesting;
import 'package:platform/platform.dart';
import 'package:process/process.dart';

import './globals.dart';
import './repository.dart';
import './stdio.dart';

const List<String> expectedEntitlements = <String>[
  'com.apple.security.cs.allow-jit',
  'com.apple.security.cs.allow-unsigned-executable-memory',
  'com.apple.security.cs.allow-dyld-environment-variables',
  'com.apple.security.network.client',
  'com.apple.security.network.server',
  'com.apple.security.cs.disable-library-validation',
];

const String kVerify = 'verify';
const String kSignatures = 'signatures';
const String kRevision = 'revision';
const String kUpstream = 'upstream';

/// Command to codesign and verify the signatures of cached binaries.
class CodesignCommand extends Command<void> {
  CodesignCommand({
    required this.checkouts,
    required this.flutterRoot,
    FrameworkRepository? framework,
  })  : fileSystem = checkouts.fileSystem,
        platform = checkouts.platform,
        stdio = checkouts.stdio,
        processManager = checkouts.processManager {
    if (framework != null) {
      _framework = framework;
    }
    argParser.addFlag(
      kVerify,
      help: 'Only verify expected binaries exist and are codesigned with entitlements.',
    );
    argParser.addFlag(
      kSignatures,
      defaultsTo: true,
      help: 'When off, this command will only verify the existence of binaries, and not their\n'
            'signatures or entitlements. Must be used with --verify flag.',
    );
    argParser.addOption(
      kUpstream,
      defaultsTo: FrameworkRepository.defaultUpstream,
      help: "The git remote URL to use as the Flutter framework's upstream.",
    );
    argParser.addOption(
      kRevision,
      help: 'The Flutter framework revision to use.',
    );
  }

  final Checkouts checkouts;
  final FileSystem fileSystem;
  final Platform platform;
  final ProcessManager processManager;
  final Stdio stdio;

  /// Root directory of the Flutter repository.
  final Directory flutterRoot;

  FrameworkRepository? _framework;
  FrameworkRepository get framework {
    return _framework ??= FrameworkRepository.localRepoAsUpstream(
      checkouts,
      upstreamPath: flutterRoot.path,
    );
  }

  @override
  String get name => 'codesign';

  @override
  String get description =>
      'For codesigning and verifying the signatures of engine binaries.';

  @override
  Future<void> run() async {
    if (!platform.isMacOS) {
      throw ConductorException(
        'Error! Expected operating system "macos", actual operating system is: '
        '"${platform.operatingSystem}"',
      );
    }

    if (argResults!['verify'] as bool != true) {
      throw ConductorException(
        'Sorry, but codesigning is not implemented yet. Please pass the '
        '--$kVerify flag to verify signatures.',
      );
    }

    String revision;
    if (argResults!.wasParsed(kRevision)) {
      stdio.printWarning(
        'Warning! When providing an arbitrary revision, the contents of the cache may not '
        'match the expected binaries in the conductor tool. It is preferred to check out '
        'the desired revision and run that version of the conductor.\n',
      );
      revision = argResults![kRevision] as String;
    } else {
      revision = ((await processManager.run(
        <String>['git', 'rev-parse', 'HEAD'],
        workingDirectory: (await framework.checkoutDirectory).path,
      )).stdout as String).trim();
      assert(revision.isNotEmpty);
    }

    await framework.checkout(revision);

    // Ensure artifacts present
    await framework.runFlutter(<String>['precache', '--android', '--ios', '--macos']);

    await verifyExist();
    if (argResults![kSignatures] as bool) {
      await verifySignatures();
    }
  }

  /// Binaries that are expected to be codesigned and have entitlements.
  ///
  /// This list should be kept in sync with the actual contents of Flutter's
  /// cache.
  Future<List<String>> get binariesWithEntitlements async {
    final String frameworkCacheDirectory = await framework.cacheDirectory;
    return <String>[
      'artifacts/engine/android-arm-profile/darwin-x64/gen_snapshot',
      'artifacts/engine/android-arm-release/darwin-x64/gen_snapshot',
      'artifacts/engine/android-arm64-profile/darwin-x64/gen_snapshot',
      'artifacts/engine/android-arm64-release/darwin-x64/gen_snapshot',
      'artifacts/engine/android-x64-profile/darwin-x64/gen_snapshot',
      'artifacts/engine/android-x64-release/darwin-x64/gen_snapshot',
      'artifacts/engine/darwin-x64-profile/gen_snapshot',
      'artifacts/engine/darwin-x64-profile/gen_snapshot_arm64',
      'artifacts/engine/darwin-x64-profile/gen_snapshot_x64',
      'artifacts/engine/darwin-x64-release/gen_snapshot',
      'artifacts/engine/darwin-x64-release/gen_snapshot_arm64',
      'artifacts/engine/darwin-x64-release/gen_snapshot_x64',
      'artifacts/engine/darwin-x64/flutter_tester',
      'artifacts/engine/darwin-x64/gen_snapshot',
      'artifacts/engine/darwin-x64/gen_snapshot_arm64',
      'artifacts/engine/darwin-x64/gen_snapshot_x64',
      'artifacts/engine/ios-profile/gen_snapshot_arm64',
      'artifacts/engine/ios-profile/gen_snapshot_armv7',
      'artifacts/engine/ios-release/gen_snapshot_arm64',
      'artifacts/engine/ios-release/gen_snapshot_armv7',
      'artifacts/engine/ios/gen_snapshot_arm64',
      'artifacts/engine/ios/gen_snapshot_armv7',
      'artifacts/libimobiledevice/idevicescreenshot',
      'artifacts/libimobiledevice/idevicesyslog',
      'artifacts/libimobiledevice/libimobiledevice-1.0.6.dylib',
      'artifacts/libplist/libplist-2.0.3.dylib',
      'artifacts/openssl/libcrypto.1.1.dylib',
      'artifacts/openssl/libssl.1.1.dylib',
      'artifacts/usbmuxd/iproxy',
      'artifacts/usbmuxd/libusbmuxd-2.0.6.dylib',
      'dart-sdk/bin/dart',
      'dart-sdk/bin/dartaotruntime',
      'dart-sdk/bin/utils/gen_snapshot',
    ]
        .map((String relativePath) =>
            fileSystem.path.join(frameworkCacheDirectory, relativePath))
        .toList();
  }

  /// Binaries that are only expected to be codesigned.
  ///
  /// This list should be kept in sync with the actual contents of Flutter's
  /// cache.
  Future<List<String>> get binariesWithoutEntitlements async {
    final String frameworkCacheDirectory = await framework.cacheDirectory;
    return <String>[
      'artifacts/engine/darwin-x64-profile/FlutterMacOS.framework/Versions/A/FlutterMacOS',
      'artifacts/engine/darwin-x64-release/FlutterMacOS.framework/Versions/A/FlutterMacOS',
      'artifacts/engine/darwin-x64/FlutterMacOS.framework/Versions/A/FlutterMacOS',
      'artifacts/engine/darwin-x64/font-subset',
      'artifacts/engine/ios-profile/Flutter.xcframework/ios-arm64_armv7/Flutter.framework/Flutter',
      'artifacts/engine/ios-profile/Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter',
      'artifacts/engine/ios-release/Flutter.xcframework/ios-arm64_armv7/Flutter.framework/Flutter',
      'artifacts/engine/ios-release/Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter',
      'artifacts/engine/ios/Flutter.xcframework/ios-arm64_armv7/Flutter.framework/Flutter',
      'artifacts/engine/ios/Flutter.xcframework/ios-arm64_x86_64-simulator/Flutter.framework/Flutter',
      'artifacts/ios-deploy/ios-deploy',
    ]
        .map((String relativePath) =>
            fileSystem.path.join(frameworkCacheDirectory, relativePath))
        .toList();
  }

  /// Verify the existence of all expected binaries in cache.
  ///
  /// This function ignores code signatures and entitlements, and is intended to
  /// be run on every commit. It should throw if either new binaries are added
  /// to the cache or expected binaries removed. In either case, this class'
  /// [binariesWithEntitlements] or [binariesWithoutEntitlements] lists should
  /// be updated accordingly.
  @visibleForTesting
  Future<void> verifyExist() async {
    final Set<String> foundFiles = <String>{};
    for (final String binaryPath
        in await findBinaryPaths(await framework.cacheDirectory)) {
      if ((await binariesWithEntitlements).contains(binaryPath)) {
        foundFiles.add(binaryPath);
      } else if ((await binariesWithoutEntitlements).contains(binaryPath)) {
        foundFiles.add(binaryPath);
      } else {
        throw ConductorException(
            'Found unexpected binary in cache: $binaryPath');
      }
    }

    final List<String> allExpectedFiles =
        (await binariesWithEntitlements) + (await binariesWithoutEntitlements);
    if (foundFiles.length < allExpectedFiles.length) {
      final List<String> unfoundFiles = allExpectedFiles
          .where(
            (String file) => !foundFiles.contains(file),
          )
          .toList();
      stdio.printError(
        'Expected binaries not found in cache:\n\n${unfoundFiles.join('\n')}\n\n'
        'If this commit is removing binaries from the cache, this test should be fixed by\n'
        'removing the relevant entry from either the "binariesWithEntitlements" or\n'
        '"binariesWithoutEntitlements" getters in dev/tools/lib/codesign.dart.',
      );
      throw ConductorException('Did not find all expected binaries!');
    }

    stdio.printStatus('All expected binaries present.');
  }

  /// Verify code signatures and entitlements of all binaries in the cache.
  @visibleForTesting
  Future<void> verifySignatures() async {
    final List<String> unsignedBinaries = <String>[];
    final List<String> wrongEntitlementBinaries = <String>[];
    final List<String> unexpectedBinaries = <String>[];
    for (final String binaryPath
        in await findBinaryPaths(await framework.cacheDirectory)) {
      bool verifySignature = false;
      bool verifyEntitlements = false;
      if ((await binariesWithEntitlements).contains(binaryPath)) {
        verifySignature = true;
        verifyEntitlements = true;
      }
      if ((await binariesWithoutEntitlements).contains(binaryPath)) {
        verifySignature = true;
      }
      if (!verifySignature && !verifyEntitlements) {
        unexpectedBinaries.add(binaryPath);
        stdio.printError('Unexpected binary $binaryPath found in cache!');
        continue;
      }
      stdio.printTrace('Verifying the code signature of $binaryPath');
      final io.ProcessResult codeSignResult = await processManager.run(
        <String>[
          'codesign',
          '-vvv',
          binaryPath,
        ],
      );
      if (codeSignResult.exitCode != 0) {
        unsignedBinaries.add(binaryPath);
        stdio.printError(
          'File "$binaryPath" does not appear to be codesigned.\n'
          'The `codesign` command failed with exit code ${codeSignResult.exitCode}:\n'
          '${codeSignResult.stderr}\n',
        );
        continue;
      }
      if (verifyEntitlements) {
        stdio.printTrace('Verifying entitlements of $binaryPath');
        if (!(await hasExpectedEntitlements(binaryPath))) {
          wrongEntitlementBinaries.add(binaryPath);
        }
      }
    }

    // First print all deviations from expectations
    if (unsignedBinaries.isNotEmpty) {
      stdio.printError('Found ${unsignedBinaries.length} unsigned binaries:');
      unsignedBinaries.forEach(stdio.printError);
    }

    if (wrongEntitlementBinaries.isNotEmpty) {
      stdio.printError('Found ${wrongEntitlementBinaries.length} binaries with unexpected entitlements:');
      wrongEntitlementBinaries.forEach(stdio.printError);
    }

    if (unexpectedBinaries.isNotEmpty) {
      stdio.printError('Found ${unexpectedBinaries.length} unexpected binaries in the cache:');
      unexpectedBinaries.forEach(print);
    }

    // Finally, exit on any invalid state
    if (unsignedBinaries.isNotEmpty) {
      throw ConductorException('Test failed because unsigned binaries detected.');
    }

    if (wrongEntitlementBinaries.isNotEmpty) {
      throw ConductorException(
        'Test failed because files found with the wrong entitlements:\n'
        '${wrongEntitlementBinaries.join('\n')}',
      );
    }

    if (unexpectedBinaries.isNotEmpty) {
      throw ConductorException('Test failed because unexpected binaries found in the cache.');
    }

    final String? desiredRevision = argResults![kRevision] as String?;
    if (desiredRevision == null) {
      stdio.printStatus('Verified that binaries are codesigned and have expected entitlements.');
    } else {
      stdio.printStatus(
        'Verified that binaries for commit $desiredRevision are codesigned and have '
        'expected entitlements.',
      );
    }
  }

  List<String>? _allBinaryPaths;

  /// Find every binary file in the given [rootDirectory].
  Future<List<String>> findBinaryPaths(String rootDirectory) async {
    if (_allBinaryPaths != null) {
      return _allBinaryPaths!;
    }
    final List<String> allBinaryPaths = <String>[];
    final io.ProcessResult result = await processManager.run(
      <String>[
        'find',
        rootDirectory,
        '-type',
        'f',
      ],
    );
    final List<String> allFiles = (result.stdout as String)
        .split('\n')
        .where((String s) => s.isNotEmpty)
        .toList();

    await Future.forEach(allFiles, (String filePath) async {
      if (await isBinary(filePath)) {
        allBinaryPaths.add(filePath);
      }
    });
    _allBinaryPaths = allBinaryPaths;
    return _allBinaryPaths!;
  }

  /// Check mime-type of file at [filePath] to determine if it is binary.
  Future<bool> isBinary(String filePath) async {
    final io.ProcessResult result = await processManager.run(
      <String>[
        'file',
        '--mime-type',
        '-b', // is binary
        filePath,
      ],
    );
    return (result.stdout as String).contains('application/x-mach-binary');
  }

  /// Check if the binary has the expected entitlements.
  Future<bool> hasExpectedEntitlements(String binaryPath) async {
    final io.ProcessResult entitlementResult = await processManager.run(
      <String>[
        'codesign',
        '--display',
        '--entitlements',
        ':-',
        binaryPath,
      ],
    );

    if (entitlementResult.exitCode != 0) {
      stdio.printError(
        'The `codesign --entitlements` command failed with exit code ${entitlementResult.exitCode}:\n'
        '${entitlementResult.stderr}\n',
      );
      return false;
    }

    bool passes = true;
    final String output = entitlementResult.stdout as String;
    for (final String entitlement in expectedEntitlements) {
      final bool entitlementExpected =
          (await binariesWithEntitlements).contains(binaryPath);
      if (output.contains(entitlement) != entitlementExpected) {
        stdio.printError(
          'File "$binaryPath" ${entitlementExpected ? 'does not have expected' : 'has unexpected'} '
          'entitlement $entitlement.',
        );
        passes = false;
      }
    }
    return passes;
  }
}
