// Copyright 2017 The Chromium 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:async';
import 'dart:convert' show utf8;

import 'package:quiver/strings.dart';

import '../application_package.dart';
import '../base/common.dart';
import '../base/io.dart';
import '../base/process.dart';
import '../base/terminal.dart';
import '../globals.dart';

/// User message when no development certificates are found in the keychain.
///
/// The user likely never did any iOS development.
const String noCertificatesInstruction = '''
═══════════════════════════════════════════════════════════════════════════════════
No valid code signing certificates were found
You can connect to your Apple Developer account by signing in with your Apple ID in Xcode
and create an iOS Development Certificate as well as a Provisioning Profile for your project by:
$fixWithDevelopmentTeamInstruction
  5- Trust your newly created Development Certificate on your iOS device
     via Settings > General > Device Management > [your new certificate] > Trust

For more information, please visit:
  https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppDistributionGuide/MaintainingCertificates/MaintainingCertificates.html

Or run on an iOS simulator without code signing
═══════════════════════════════════════════════════════════════════════════════════''';
/// User message when there are no provisioning profile for the current app bundle identifier.
///
/// The user did iOS development but never on this project and/or device.
const String noProvisioningProfileInstruction = '''
═══════════════════════════════════════════════════════════════════════════════════
No Provisioning Profile was found for your project's Bundle Identifier or your device.
You can create a new Provisioning Profile for your project in Xcode for your
team by:
$fixWithDevelopmentTeamInstruction

It's also possible that a previously installed app with the same Bundle Identifier was
signed with a different certificate.

For more information, please visit:
  https://flutter.io/setup/#deploy-to-ios-devices

Or run on an iOS simulator without code signing
═══════════════════════════════════════════════════════════════════════════════════''';
/// Fallback error message for signing issues.
///
/// Couldn't auto sign the app but can likely solved by retracing the signing flow in Xcode.
const String noDevelopmentTeamInstruction = '''
═══════════════════════════════════════════════════════════════════════════════════
Building a deployable iOS app requires a selected Development Team with a Provisioning Profile
Please ensure that a Development Team is selected by:
$fixWithDevelopmentTeamInstruction

For more information, please visit:
  https://flutter.io/setup/#deploy-to-ios-devices

Or run on an iOS simulator without code signing
═══════════════════════════════════════════════════════════════════════════════════''';
const String fixWithDevelopmentTeamInstruction = '''
  1- Open the Flutter project's Xcode target with
       open ios/Runner.xcworkspace
  2- Select the 'Runner' project in the navigator then the 'Runner' target
     in the project settings
  3- In the 'General' tab, make sure a 'Development Team' is selected. You may need to
         - Log in with your Apple ID in Xcode first
         - Ensure you have a valid unique Bundle ID
         - Register your device with your Apple Developer Account
         - Let Xcode automatically provision a profile for your app
  4- Build or run your project again''';

final RegExp _securityFindIdentityDeveloperIdentityExtractionPattern =
    new RegExp(r'^\s*\d+\).+"(.+Developer.+)"$');
final RegExp _securityFindIdentityCertificateCnExtractionPattern = new RegExp(r'.*\(([a-zA-Z0-9]+)\)');
final RegExp _certificateOrganizationalUnitExtractionPattern = new RegExp(r'OU=([a-zA-Z0-9]+)');

/// Given a [BuildableIOSApp], this will try to find valid development code
/// signing identities in the user's keychain prompting a choice if multiple
/// are found.
///
/// Returns a set of build configuration settings that uses the selected
/// signing identities.
///
/// Will return null if none are found, if the user cancels or if the Xcode
/// project has a development team set in the project's build settings.
Future<Map<String, String>> getCodeSigningIdentityDevelopmentTeam({
  BuildableIOSApp iosApp,
  bool usesTerminalUi = true
}) async{
  if (iosApp.buildSettings == null)
    return null;

  // If the user already has it set in the project build settings itself,
  // continue with that.
  if (isNotEmpty(iosApp.buildSettings['DEVELOPMENT_TEAM'])) {
    printStatus(
      'Automatically signing iOS for device deployment using specified development '
      'team in Xcode project: ${iosApp.buildSettings['DEVELOPMENT_TEAM']}'
    );
    return null;
  }

  if (isNotEmpty(iosApp.buildSettings['PROVISIONING_PROFILE']))
    return null;

  // If the user's environment is missing the tools needed to find and read
  // certificates, abandon. Tools should be pre-equipped on macOS.
  if (!exitsHappy(const <String>['which', 'security']) || !exitsHappy(const <String>['which', 'openssl']))
    return null;

  const List<String> findIdentityCommand =
      const <String>['security', 'find-identity', '-p', 'codesigning', '-v'];
  final List<String> validCodeSigningIdentities = runCheckedSync(findIdentityCommand)
      .split('\n')
      .map<String>((String outputLine) {
        return _securityFindIdentityDeveloperIdentityExtractionPattern
            .firstMatch(outputLine)
            ?.group(1);
      })
      .where(isNotEmpty)
      .toSet() // Unique.
      .toList();

  final String signingIdentity = await _chooseSigningIdentity(validCodeSigningIdentities, usesTerminalUi);

  // If none are chosen, return null.
  if (signingIdentity == null)
    return null;

  printStatus('Signing iOS app for device deployment using developer identity: "$signingIdentity"');

  final String signingCertificateId =
      _securityFindIdentityCertificateCnExtractionPattern
          .firstMatch(signingIdentity)
          ?.group(1);

  // If `security`'s output format changes, we'd have to update the above regex.
  if (signingCertificateId == null)
    return null;

  final String signingCertificate = runCheckedSync(
    <String>['security', 'find-certificate', '-c', signingCertificateId, '-p']
  );

  final Process opensslProcess = await runCommand(const <String>['openssl', 'x509', '-subject']);
  opensslProcess.stdin
      ..write(signingCertificate)
      ..close();

  final String opensslOutput = await utf8.decodeStream(opensslProcess.stdout);
  // Fire and forget discard of the stderr stream so we don't hold onto resources.
  // Don't care about the result.
  opensslProcess.stderr.drain<String>(); // ignore: unawaited_futures

  if (await opensslProcess.exitCode != 0)
    return null;

  final Map<String, String> signingConfigs = <String, String> {
    'DEVELOPMENT_TEAM': _certificateOrganizationalUnitExtractionPattern
      .firstMatch(opensslOutput)
      ?.group(1),
  };

  if (opensslOutput.contains('iPhone Developer: Google Development')) {
    signingConfigs['PROVISIONING_PROFILE_SPECIFIER'] = 'Google Development';
    signingConfigs['CODE_SIGN_STYLE'] = 'Manual';
    printStatus("Manually selecting Google's mobile provisioning profile (see go/google-flutter-signing).");
  }

  return signingConfigs;
}

Future<String> _chooseSigningIdentity(List<String> validCodeSigningIdentities, bool usesTerminalUi) async {
  // The user has no valid code signing identities.
  if (validCodeSigningIdentities.isEmpty) {
    printError(noCertificatesInstruction, emphasis: true);
    throwToolExit('No development certificates available to code sign app for device deployment');
  }

  if (validCodeSigningIdentities.length == 1)
    return validCodeSigningIdentities.first;

  if (validCodeSigningIdentities.length > 1) {
    final String savedCertChoice = config.getValue('ios-signing-cert');

    if (savedCertChoice != null) {
      if (validCodeSigningIdentities.contains(savedCertChoice)) {
        printStatus('Found saved certificate choice "$savedCertChoice". To clear, use "flutter config".');
        return savedCertChoice;
      }
      else {
        printError('Saved signing certificate "$savedCertChoice" is not a valid development certificate');
      }
    }

    // If terminal UI can't be used, just attempt with the first valid certificate
    // since we can't ask the user.
    if (!usesTerminalUi)
      return validCodeSigningIdentities.first;

    final int count = validCodeSigningIdentities.length;
    printStatus(
      'Multiple valid development certificates available (your choice will be saved):',
      emphasis: true,
    );
    for (int i=0; i<count; i++) {
      printStatus('  ${i+1}) ${validCodeSigningIdentities[i]}', emphasis: true);
    }
    printStatus('  a) Abort', emphasis: true);

    final String choice = await terminal.promptForCharInput(
      new List<String>.generate(count, (int number) => '${number + 1}')
          ..add('a'),
      prompt: 'Please select a certificate for code signing',
      displayAcceptedCharacters: true,
      defaultChoiceIndex: 0, // Just pressing enter chooses the first one.
    );

    if (choice == 'a') {
      throwToolExit('Aborted. Code signing is required to build a deployable iOS app.');
    } else {
      final String selectedCert = validCodeSigningIdentities[int.parse(choice) - 1];
      printStatus('Certificate choice "$selectedCert" saved');
      config.setValue('ios-signing-cert', selectedCert);
      return selectedCert;
    }
  }

  return null;
}
