// 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',
  '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.');
}
