// Copyright 2019 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:file/file.dart';
import 'package:file/local.dart';
import 'package:logging/logging.dart';
import 'package:process/process.dart';

const String kNotNotarizedMessage = 'test-requirement: code failed to satisfy specified code requirement(s)';

enum VerificationResult {
  unsigned,
  codesignedOnly,
  codesignedAndNotarized,
}

class VerificationService {
  VerificationService({
    required this.binaryPath,
    required this.logger,
    this.fs = const LocalFileSystem(),
    this.pm = const LocalProcessManager(),
  }) {
    if (!fs.file(binaryPath).existsSync()) {
      throw Exception(
        'Input file `$binaryPath` does not exist--please provide the path to a '
        'valid binary to verify.',
      );
    }
    if (!pm.canRun('codesign')) {
      throw Exception(
        'The binary `codesign` is required to run this tool. Do you have '
        'Xcode installed?',
      );
    }
  }

  final Logger logger;
  final String binaryPath;
  final FileSystem fs;
  final ProcessManager pm;

  late final String _codesignTimestamp;
  late final String _format;
  late final String _signatureSize;
  late final String _codesignId;
  bool? _notarizationStatus;

  Future<VerificationResult> run() async {
    if (!await _codesignDisplay()) {
      return VerificationResult.unsigned;
    }
    await _notarization();
    logger.info(present());
    return _notarizationStatus! ? VerificationResult.codesignedAndNotarized : VerificationResult.codesignedOnly;
  }

  Future<void> _notarization() async {
    final List<String> command = <String>[
      'codesign',
      '--verify',
      '-v',
      // force online notarization check
      '-R=notarized',
      '--check-notarization',
      binaryPath,
    ];
    final io.ProcessResult result = await pm.run(command);

    // This usually means it does not satisfy notarization requirement
    if (result.exitCode == 3 && (result.stderr as String).contains(kNotNotarizedMessage)) {
      _notarizationStatus = false;
      return;
    }
    if (result.exitCode != 0) {
      throw Exception('''
Command `${command.join(' ')}` failed with code ${result.exitCode}

${result.stderr}
''');
    }
    final String stderr = result.stderr as String;
    if (stderr.contains('explicit requirement satisfied')) {
      _notarizationStatus = true;
      return;
    }
    throw UnimplementedError('Failed parsing the output of `${command.join(' ')}`:\n\n$stderr');
  }

  String present() {
    return '''
Authority:      $_codesignId
Time stamp:     $_codesignTimestamp
Format:         $_format
Signature size: $_signatureSize
Notarization:   $_notarizationStatus
''';
  }

  /// Display overall information, intended to be machine parseable
  ///
  /// Output is of the format:
  ///
  /// Executable=/Users/developer/Downloads/mybinary
  /// Identifier=mybinary
  /// Format=Mach-O thin (x86_64)
  /// CodeDirectory v=20500 size=38000 flags=0x10000(runtime) hashes=1177+7 location=embedded
  /// Signature size=8979
  /// Authority=Developer ID Application: Dev Shop ABC (ABCC0VV123)
  /// Authority=Developer ID Certification Authority
  /// Authority=Apple Root CA
  /// Timestamp=Jan 9, 2023 at 9:39:07 AM
  /// Info.plist=not bound
  /// TeamIdentifier=ABCC0VV123
  /// Runtime Version=13.1.0
  /// Sealed Resources=none
  /// Internal requirements count=1 size=164
  Future<bool> _codesignDisplay() async {
    final List<String> command = <String>[
      'codesign',
      '--display',
      '-vv',
      binaryPath,
    ];
    final io.ProcessResult result = await pm.run(command);

    if (result.exitCode == 1) {
      logger.severe('''
File $binaryPath is not codesigned. To manually verify, run:

codesign --display -vv $binaryPath
''');
      return false;
    } else if (result.exitCode != 0) {
      throw Exception(
        'Command `${command.join(' ')}` failed with code ${result.exitCode}\n\n'
        '${result.stderr}',
      );
    }

    final List<String> lines = result.stderr.toString().trim().split('\n');
    for (final String line in lines) {
      if (line.trim().isEmpty) {
        continue;
      }
      final List<String> segments = line.split('=');
      final String name = segments.first;

      switch (name) {
        case 'Executable':
        case 'Identifier':
        case 'CodeDirectory v':
        case 'Info.plist':
        // TeamIdentifier is redundant with the Authority field
        case 'TeamIdentifier':
        case 'Runtime Version':
        case 'Sealed Resources':
        case 'Internal requirements count':
          break;
        case 'Signature size':
          _signatureSize = segments.sublist(1).join();
          break;
        case 'Authority':
          if (segments[1].startsWith('Developer ID Application')) {
            _codesignId = segments[1];
          }
          break;
        case 'Timestamp':
          _codesignTimestamp = segments[1];
          break;
        case 'Format':
          _format = segments.sublist(1).join();
          break;
        default:
          logger.warning(
            'Do not know how to parse a $name, skipping this field.',
          );
      }
    }
    return true;
  }
}
