// 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';
import 'package:path/path.dart' as path;

String get repoRoot => path.normalize(path.join(path.dirname(Platform.script.toFilePath()), '..', '..'));
String get cacheDirectory => path.normalize(path.join(repoRoot, 'bin', 'cache'));

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

/// Find every binary file in the given [rootDirectory]
List<String> findBinaryPaths([String rootDirectory]) {
  rootDirectory ??= cacheDirectory;
  final ProcessResult result = Process.runSync(
    'find',
    <String>[
      rootDirectory,
      '-type',
      'f',
      '-perm',
      '+111', // is executable
    ],
  );
  final List<String> allFiles = (result.stdout as String).split('\n').where((String s) => s.isNotEmpty).toList();
  return allFiles.where(isBinary).toList();
}

/// Given the path to a stamp file, read the contents.
///
/// Will throw if the file doesn't exist.
String readStamp(String filePath) {
  final File file = File(filePath);
  if (!file.existsSync()) {
    throw 'Error! Stamp file $filePath does not exist!';
  }
  return file.readAsStringSync().trim();
}

/// Return whether or not the flutter cache is up to date.
bool checkCacheIsCurrent() {
  try {
    final String dartSdkStamp = readStamp(path.join(cacheDirectory, 'engine-dart-sdk.stamp'));
    final String engineVersion = readStamp(path.join(repoRoot, 'bin', 'internal', 'engine.version'));
    return dartSdkStamp == engineVersion;
  } catch (e) {
    print(e);
    return false;
  }
}

List<String> get binariesWithEntitlements => List<String>.unmodifiable(<String>[
  'idevice_id',
  'ideviceinfo',
  'idevicename',
  'idevicescreenshot',
  'idevicesyslog',
  'libimobiledevice.6.dylib',
  'ideviceinstaller',
  'libplist.3.dylib',
  'iproxy',
  'libusbmuxd.4.dylib',
  'libssl.1.0.0.dylib',
  'libcrypto.1.0.0.dylib',
  'libzip.5.0.dylib',
  'libzip.5.dylib',
  'gen_snapshot',
  'dart',
  'flutter_tester',
  'gen_snapshot_arm64',
  'gen_snapshot_armv7',
]);

List<String> get expectedEntitlements => List<String>.unmodifiable(<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',
]);


/// Check if the binary has the expected entitlements.
bool hasExpectedEntitlements(String binaryPath) {
  try {
    final ProcessResult entitlementResult = Process.runSync(
      'codesign',
      <String>[
        '--display',
        '--entitlements',
        ':-',
        binaryPath,
      ],
    );

    if (entitlementResult.exitCode != 0) {
      print('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 = binariesWithEntitlements.contains(path.basename(binaryPath));
      if (output.contains(entitlement) != entitlementExpected) {
        print('File "$binaryPath" ${entitlementExpected ? 'does not have expected' : 'has unexpected'} entitlement $entitlement.');
        passes = false;
      }
    }
    return passes;
  } catch (e) {
    print(e);
    return false;
  }
}

void main() {
  if (!Platform.isMacOS) {
    print('Error! Expected operating system "macos", actual operating system '
      'is: "${Platform.operatingSystem}"');
    exit(1);
  }

  if (!checkCacheIsCurrent()) {
    print(
      'Warning! Your cache is either not present or not matching your flutter\n'
      'version. Run a `flutter` command to update your cache, and re-try this\n'
      'test.');
    exit(1);
  }

  final List<String> unsignedBinaries = <String>[];
  final List<String> wrongEntitlementBinaries = <String>[];
  for (final String binaryPath in findBinaryPaths(cacheDirectory)) {
    print('Verifying the code signature of $binaryPath');
    final ProcessResult codeSignResult = Process.runSync(
      'codesign',
      <String>[
        '-vvv',
        binaryPath,
      ],
    );
    if (codeSignResult.exitCode != 0) {
      unsignedBinaries.add(binaryPath);
      print('File "$binaryPath" does not appear to be codesigned.\n'
            'The `codesign` command failed with exit code ${codeSignResult.exitCode}:\n'
            '${codeSignResult.stderr}\n');
      continue;
    } else {
      print('Verifying entitlements of $binaryPath');
      if (!hasExpectedEntitlements(binaryPath)) {
        wrongEntitlementBinaries.add(binaryPath);
      }
    }
  }

  if (unsignedBinaries.isNotEmpty) {
    print('Found ${unsignedBinaries.length} unsigned binaries:');
    unsignedBinaries.forEach(print);
  }

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

  if (unsignedBinaries.isNotEmpty) {
    // TODO(jmagman): Also exit if `wrongEntitlementBinaries.isNotEmpty` after https://github.com/flutter/flutter/issues/46704 is done.
    exit(1);
  }

  print('Verified that binaries are codesigned and have expected entitlements.');
}
