// 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:async';
import 'dart:convert';

import 'package:flutter_tools/src/base/config.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/globals_null_migrated.dart' as globals;
import 'package:flutter_tools/src/ios/code_signing.dart';

import '../../src/common.dart';
import '../../src/fake_process_manager.dart';

const String kCertificates = '''
1) 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 "iPhone Developer: Profile 1 (1111AAAA11)"
2) da4b9237bacccdf19c0760cab7aec4a8359010b0 "iPhone Developer: Profile 2 (2222BBBB22)"
3) 5bf1fd927dfb8679496a2e6cf00cbe50c1c87145 "iPhone Developer: Profile 3 (3333CCCC33)"
    3 valid identities found''';

void main() {
  group('Auto signing', () {
    late Config testConfig;
    late AnsiTerminal testTerminal;
    late BufferLogger logger;
    late Platform macosPlatform;

    setUp(() async {
      logger = BufferLogger.test();
      testConfig = Config.test();
      testTerminal = TestTerminal();
      testTerminal.usesTerminalUi = true;
      macosPlatform = FakePlatform(operatingSystem: 'macos');
    });

    testWithoutContext('No auto-sign if Xcode project settings are not available', () async {
      final Map<String, String>? signingConfigs = await getCodeSigningIdentityDevelopmentTeamBuildSetting(
        buildSettings: null,
        processManager: FakeProcessManager.empty(),
        platform: macosPlatform,
        logger: logger,
        config: testConfig,
        terminal: testTerminal,
      );
      expect(signingConfigs, isNull);
    });

    testWithoutContext('No discovery if development team specified in Xcode project', () async {
      final Map<String, String>? signingConfigs = await getCodeSigningIdentityDevelopmentTeamBuildSetting(
        buildSettings: <String, String>{
          'DEVELOPMENT_TEAM': 'abc',
        },
        platform: macosPlatform,
        processManager: FakeProcessManager.empty(),
        logger: logger,
        config: testConfig,
        terminal: testTerminal,
      );
      expect(signingConfigs, isNull);
      expect(logger.statusText, equals(
        'Automatically signing iOS for device deployment using specified development team in Xcode project: abc\n'
      ));
    });

    testWithoutContext('No auto-sign if security or openssl not available', () async {
      final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['which', 'security'],
          exitCode: 1,
        ),
      ]);

      final String? developmentTeam = await getCodeSigningIdentityDevelopmentTeam(
        processManager: processManager,
        platform: macosPlatform,
        logger: logger,
        config: testConfig,
        terminal: testTerminal,
      );
      expect(developmentTeam, isNull);
      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('No valid code signing certificates', () async {
      final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['which', 'security'],
        ),
        const FakeCommand(
          command: <String>['which', 'openssl'],
        ),
        const FakeCommand(
          command: <String>['security', 'find-identity', '-p', 'codesigning', '-v'],
        ),
      ]);

      final String? developmentTeam = await getCodeSigningIdentityDevelopmentTeam(
        processManager: processManager,
        platform: macosPlatform,
        logger: logger,
        config: testConfig,
        terminal: testTerminal,
      );

      expect(developmentTeam, isNull);
      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('No valid code signing certificates shows instructions', () async {
      final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['which', 'security'],
        ),
        const FakeCommand(
          command: <String>['which', 'openssl'],
        ),
        const FakeCommand(
          command: <String>['security', 'find-identity', '-p', 'codesigning', '-v'],
        ),
      ]);

      await expectLater(() => getCodeSigningIdentityDevelopmentTeamBuildSetting(
        buildSettings: <String, String>{},
        platform: macosPlatform,
        processManager: processManager,
        logger: logger,
        config: testConfig,
        terminal: testTerminal,
      ), throwsToolExit(message: 'No development certificates available to code sign app for device deployment'));
    });

    testWithoutContext('No valid code signing certificates on non-macOS platform', () async {
      final FakeProcessManager processManager = FakeProcessManager.empty();

      final String? developmentTeam = await getCodeSigningIdentityDevelopmentTeam(
        processManager: processManager,
        platform: FakePlatform(),
        logger: logger,
        config: testConfig,
        terminal: testTerminal,
      );

      expect(developmentTeam, isNull);
      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('Test single identity and certificate organization development team build setting', () async {
      final Completer<void> completer = Completer<void>();
      final StreamController<List<int>> controller = StreamController<List<int>>();
      const String certificates = '''
1) 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 "iPhone Developer: Profile 1 (1111AAAA11)"
    1 valid identities found''';
      final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['which', 'security'],
        ),
        const FakeCommand(
          command: <String>['which', 'openssl'],
        ),
        const FakeCommand(
          command: <String>['security', 'find-identity', '-p', 'codesigning', '-v'],
          stdout: certificates,
        ),
        const FakeCommand(
          command: <String>['security', 'find-certificate', '-c', '1111AAAA11', '-p'],
          stdout: 'This is a fake certificate',
        ),
        FakeCommand(
          command: const <String>['openssl', 'x509', '-subject'],
          stdin: IOSink(controller.sink),
          stdout: 'subject= /CN=iPhone Developer: Profile 1 (1111AAAA11)/OU=3333CCCC33/O=My Team/C=US',
          completer: completer,
        )
      ]);

      // Verify that certificate value is passed into openssl command.
      String? stdin;
      controller.stream.listen((List<int> chunk) {
        stdin = utf8.decode(chunk);
        completer.complete();
      });

      final Map<String, String>? signingConfigs = await getCodeSigningIdentityDevelopmentTeamBuildSetting(
        buildSettings: <String, String>{
          'bogus': 'bogus',
        },
        platform: macosPlatform,
        processManager: processManager,
        logger: logger,
        config: testConfig,
        terminal: testTerminal,
      );

      expect(logger.statusText, contains('iPhone Developer: Profile 1 (1111AAAA11)'));
      expect(logger.errorText, isEmpty);
      expect(stdin, 'This is a fake certificate');
      expect(signingConfigs, <String, String>{'DEVELOPMENT_TEAM': '3333CCCC33'});
      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('Test single identity and certificate organization development team', () async {
      final Completer<void> completer = Completer<void>();
      final StreamController<List<int>> controller = StreamController<List<int>>();
      const String certificates = '''
1) 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 "iPhone Developer: Profile 1 (1111AAAA11)"
    1 valid identities found''';
      final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['which', 'security'],
        ),
        const FakeCommand(
          command: <String>['which', 'openssl'],
        ),
        const FakeCommand(
          command: <String>['security', 'find-identity', '-p', 'codesigning', '-v'],
          stdout: certificates,
        ),
        const FakeCommand(
          command: <String>['security', 'find-certificate', '-c', '1111AAAA11', '-p'],
          stdout: 'This is a fake certificate',
        ),
        FakeCommand(
          command: const <String>['openssl', 'x509', '-subject'],
          stdin: IOSink(controller.sink),
          stdout: 'subject= /CN=iPhone Developer: Profile 1 (1111AAAA11)/OU=3333CCCC33/O=My Team/C=US',
          completer: completer,
        )
      ]);

      // Verify that certificate value is passed into openssl command.
      String? stdin;
      controller.stream.listen((List<int> chunk) {
        stdin = utf8.decode(chunk);
        completer.complete();
      });

      final String? developmentTeam = await getCodeSigningIdentityDevelopmentTeam(
        processManager: processManager,
        platform: macosPlatform,
        logger: logger,
        config: testConfig,
        terminal: testTerminal,
      );

      expect(logger.statusText, contains('iPhone Developer: Profile 1 (1111AAAA11)'));
      expect(logger.errorText, isEmpty);
      expect(stdin, 'This is a fake certificate');
      expect(developmentTeam, '3333CCCC33');
      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('Test single identity (Catalina format) and certificate organization works', () async {
      final Completer<void> completer = Completer<void>();
      final StreamController<List<int>> controller = StreamController<List<int>>();
      const String certificates = '''
1) 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 "Apple Development: Profile 1 (1111AAAA11)"
    1 valid identities found''';
      final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['which', 'security'],
        ),
        const FakeCommand(
          command: <String>['which', 'openssl'],
        ),
        const FakeCommand(
          command: <String>['security', 'find-identity', '-p', 'codesigning', '-v'],
          stdout: certificates,
        ),
        const FakeCommand(
          command: <String>['security', 'find-certificate', '-c', '1111AAAA11', '-p'],
          stdout: 'This is a fake certificate',
        ),
        FakeCommand(
          command: const <String>['openssl', 'x509', '-subject'],
          stdin: IOSink(controller.sink),
          stdout: 'subject= /CN=iPhone Developer: Profile 1 (1111AAAA11)/OU=3333CCCC33/O=My Team/C=US',
          completer: completer,
        )
      ]);

      // Verify that certificate value is passed into openssl command.
      String? stdin;
      controller.stream.listen((List<int> chunk) {
        stdin = utf8.decode(chunk);
        completer.complete();
      });

      final String? developmentTeam = await getCodeSigningIdentityDevelopmentTeam(
        processManager: processManager,
        platform: macosPlatform,
        logger: logger,
        config: testConfig,
        terminal: testTerminal,
      );

      expect(logger.statusText, contains('Apple Development: Profile 1 (1111AAAA11)'));
      expect(logger.errorText, isEmpty);
      expect(stdin, 'This is a fake certificate');
      expect(developmentTeam, '3333CCCC33');
      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('Test multiple identity and certificate organization works', () async {
      final Completer<void> completer = Completer<void>();
      final StreamController<List<int>> controller = StreamController<List<int>>();
      mockTerminalStdInStream = Stream<String>.value('3');
      final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['which', 'security'],
        ),
        const FakeCommand(
          command: <String>['which', 'openssl'],
        ),
        const FakeCommand(
          command: <String>['security', 'find-identity', '-p', 'codesigning', '-v'],
          stdout: kCertificates,
        ),
        const FakeCommand(
          command: <String>['security', 'find-certificate', '-c', '3333CCCC33', '-p'],
          stdout: 'This is a fake certificate',
        ),
        FakeCommand(
          command: const <String>['openssl', 'x509', '-subject'],
          stdin: IOSink(controller.sink),
          stdout: 'subject= /CN=iPhone Developer: Profile 3 (3333CCCC33)/OU=4444DDDD44/O=My Team/C=US',
          completer: completer,
        )
      ]);

      // Verify that certificate value is passed into openssl command.
      String? stdin;
      controller.stream.listen((List<int> chunk) {
        stdin = utf8.decode(chunk);
        completer.complete();
      });

      final String? developmentTeam = await getCodeSigningIdentityDevelopmentTeam(
        processManager: processManager,
        platform: macosPlatform,
        logger: logger,
        config: testConfig,
        terminal: testTerminal,
      );

      expect(
        logger.statusText,
        contains('Please select a certificate for code signing [<bold>1</bold>|2|3|a]: 3'),
      );
      expect(
        logger.statusText,
        contains('Signing iOS app for device deployment using developer identity: "iPhone Developer: Profile 3 (3333CCCC33)"'),
      );
      expect(logger.errorText, isEmpty);
      expect(stdin, 'This is a fake certificate');
      expect(developmentTeam, '4444DDDD44');
      expect(testConfig.getValue('ios-signing-cert'), 'iPhone Developer: Profile 3 (3333CCCC33)');
      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('Test multiple identity in machine mode works', () async {
      testTerminal.usesTerminalUi = false;
      final Completer<void> completer = Completer<void>();
      final StreamController<List<int>> controller = StreamController<List<int>>();
      final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['which', 'security'],
        ),
        const FakeCommand(
          command: <String>['which', 'openssl'],
        ),
        const FakeCommand(
          command: <String>['security', 'find-identity', '-p', 'codesigning', '-v'],
          stdout: kCertificates,
        ),
        const FakeCommand(
          command: <String>['security', 'find-certificate', '-c', '1111AAAA11', '-p'],
          stdout: 'This is a fake certificate',
        ),
        FakeCommand(
          command: const <String>['openssl', 'x509', '-subject'],
          stdin: IOSink(controller.sink),
          stdout: 'subject= /CN=iPhone Developer: Profile 3 (1111AAAA11)/OU=5555EEEE55/O=My Team/C=US',
          completer: completer,
        )
      ]);

      // Verify that certificate value is passed into openssl command.
      String? stdin;
      controller.stream.listen((List<int> chunk) {
        stdin = utf8.decode(chunk);
        completer.complete();
      });

      final String? developmentTeam = await getCodeSigningIdentityDevelopmentTeam(
        processManager: processManager,
        platform: macosPlatform,
        logger: logger,
        config: testConfig,
        terminal: testTerminal,
      );

      expect(
        logger.statusText,
        contains('Signing iOS app for device deployment using developer identity: "iPhone Developer: Profile 1 (1111AAAA11)"'),
      );
      expect(logger.errorText, isEmpty);
      expect(stdin, 'This is a fake certificate');
      expect(developmentTeam, '5555EEEE55');
      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('Test saved certificate used', () async {
      testConfig.setValue('ios-signing-cert', 'iPhone Developer: Profile 3 (3333CCCC33)');
      final Completer<void> completer = Completer<void>();
      final StreamController<List<int>> controller = StreamController<List<int>>();
      final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['which', 'security'],
        ),
        const FakeCommand(
          command: <String>['which', 'openssl'],
        ),
        const FakeCommand(
          command: <String>['security', 'find-identity', '-p', 'codesigning', '-v'],
          stdout: kCertificates,
        ),
        const FakeCommand(
          command: <String>['security', 'find-certificate', '-c', '3333CCCC33', '-p'],
          stdout: 'This is a fake certificate',
        ),
        FakeCommand(
          command: const <String>['openssl', 'x509', '-subject'],
          stdin: IOSink(controller.sink),
          stdout: 'subject= /CN=iPhone Developer: Profile 3 (3333CCCC33)/OU=4444DDDD44/O=My Team/C=US',
          completer: completer,
        )
      ]);

      // Verify that certificate value is passed into openssl command.
      String? stdin;
      controller.stream.listen((List<int> chunk) {
        stdin = utf8.decode(chunk);
        completer.complete();
      });

      final String? developmentTeam = await getCodeSigningIdentityDevelopmentTeam(
        processManager: processManager,
        platform: macosPlatform,
        logger: logger,
        config: testConfig,
        terminal: testTerminal,
      );

      expect(
        logger.statusText,
        contains('Found saved certificate choice "iPhone Developer: Profile 3 (3333CCCC33)". To clear, use "flutter config"'),
      );
      expect(
        logger.statusText,
        contains('Signing iOS app for device deployment using developer identity: "iPhone Developer: Profile 3 (3333CCCC33)"'),
      );
      expect(logger.errorText, isEmpty);
      expect(stdin, 'This is a fake certificate');
      expect(developmentTeam, '4444DDDD44');
      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('Test invalid saved certificate shows error and prompts again', () async {
      testConfig.setValue('ios-signing-cert', 'iPhone Developer: Invalid Profile');
      mockTerminalStdInStream = Stream<String>.value('3');
      final Completer<void> completer = Completer<void>();
      final StreamController<List<int>> controller = StreamController<List<int>>();
      final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['which', 'security'],
        ),
        const FakeCommand(
          command: <String>['which', 'openssl'],
        ),
        const FakeCommand(
          command: <String>['security', 'find-identity', '-p', 'codesigning', '-v'],
          stdout: kCertificates,
        ),
        const FakeCommand(
          command: <String>['security', 'find-certificate', '-c', '3333CCCC33', '-p'],
          stdout: 'This is a fake certificate',
        ),
        FakeCommand(
          command: const <String>['openssl', 'x509', '-subject'],
          stdin: IOSink(controller.sink),
          stdout: 'subject= /CN=iPhone Developer: Profile 3 (3333CCCC33)/OU=4444DDDD44/O=My Team/C=US',
          completer: completer,
        )
      ]);

      // Verify that certificate value is passed into openssl command.
      String? stdin;
      controller.stream.listen((List<int> chunk) {
        stdin = utf8.decode(chunk);
        completer.complete();
      });

      final String? developmentTeam = await getCodeSigningIdentityDevelopmentTeam(
        processManager: processManager,
        platform: macosPlatform,
        logger: logger,
        config: testConfig,
        terminal: testTerminal,
      );

      expect(
        logger.errorText,
        containsIgnoringWhitespace('Saved signing certificate "iPhone Developer: Invalid Profile" is not a valid development certificate'),
      );
      expect(
        logger.statusText,
        contains('Certificate choice "iPhone Developer: Profile 3 (3333CCCC33)"'),
      );
      expect(developmentTeam, '4444DDDD44');
      expect(stdin, 'This is a fake certificate');
      expect(testConfig.getValue('ios-signing-cert'), 'iPhone Developer: Profile 3 (3333CCCC33)');
      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('find-identity failure', () async {
      final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['which', 'security'],
        ),
        const FakeCommand(
          command: <String>['which', 'openssl'],
        ),
        const FakeCommand(
          command: <String>['security', 'find-identity', '-p', 'codesigning', '-v'],
          exitCode: 1,
        ),
      ]);

      final String? developmentTeam = await getCodeSigningIdentityDevelopmentTeam(
        processManager: processManager,
        platform: macosPlatform,
        logger: logger,
        config: testConfig,
        terminal: testTerminal,
      );
      expect(developmentTeam, isNull);
      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('find-certificate failure', () async {
      mockTerminalStdInStream = Stream<String>.value('3');

      final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['which', 'security'],
        ),
        const FakeCommand(
          command: <String>['which', 'openssl'],
        ),
        const FakeCommand(
          command: <String>['security', 'find-identity', '-p', 'codesigning', '-v'],
          stdout: kCertificates,
        ),
        const FakeCommand(
          command: <String>['security', 'find-certificate', '-c', '3333CCCC33', '-p'],
          exitCode: 1,
        ),
      ]);

      final String? developmentTeam = await getCodeSigningIdentityDevelopmentTeam(
        processManager: processManager,
        platform: macosPlatform,
        logger: logger,
        config: testConfig,
        terminal: testTerminal,
      );
      expect(developmentTeam, isNull);
      expect(processManager, hasNoRemainingExpectations);
    });
  });
}

late Stream<String> mockTerminalStdInStream;

class TestTerminal extends AnsiTerminal {
  TestTerminal() : super(stdio: globals.stdio, platform: globals.platform);

  @override
  String bolden(String message) => '<bold>$message</bold>';

  @override
  Stream<String> get keystrokes {
    return mockTerminalStdInStream;
  }

  @override
  int get preferredStyle => 0;
}
