// 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.

// @dart = 2.8

import 'package:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.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/version.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/ios/xcode_build_settings.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';

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

const String xcodebuild = '/usr/bin/xcodebuild';

void main() {
  group('MockProcessManager', () {
    setUp(() {
      final FileSystem fileSystem = MemoryFileSystem.test();
      fileSystem.file(xcodebuild).createSync(recursive: true);
    });
  });

  const FakeCommand kWhichSysctlCommand = FakeCommand(
    command: <String>[
      'which',
      'sysctl',
    ],
  );

  // x64 host.
  const FakeCommand kx64CheckCommand = FakeCommand(
    command: <String>[
      'sysctl',
      'hw.optional.arm64',
    ],
    exitCode: 1,
  );

  // ARM host.
  const FakeCommand kARMCheckCommand = FakeCommand(
    command: <String>[
      'sysctl',
      'hw.optional.arm64',
    ],
    stdout: 'hw.optional.arm64: 1',
  );

  FakeProcessManager fakeProcessManager;
  XcodeProjectInterpreter xcodeProjectInterpreter;
  FakePlatform platform;
  FileSystem fileSystem;
  BufferLogger logger;

  setUp(() {
    fakeProcessManager = FakeProcessManager.empty();
    platform = FakePlatform(operatingSystem: 'macos');
    fileSystem = MemoryFileSystem.test();
    fileSystem.file(xcodebuild).createSync(recursive: true);
    logger = BufferLogger.test();
    xcodeProjectInterpreter = XcodeProjectInterpreter(
      logger: logger,
      fileSystem: fileSystem,
      platform: platform,
      processManager: fakeProcessManager,
      usage: TestUsage(),
    );
  });

  testWithoutContext('xcodebuild versionText returns null when xcodebuild is not fully installed', () {
    fakeProcessManager.addCommands(const <FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>['xcrun', 'xcodebuild', '-version'],
        stdout: "xcode-select: error: tool 'xcodebuild' requires Xcode, "
            "but active developer directory '/Library/Developer/CommandLineTools' "
            'is a command line tools instance',
        exitCode: 1,
      ),
    ]);

    expect(xcodeProjectInterpreter.versionText, isNull);
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext('xcodebuild versionText returns null when xcodebuild is not installed', () {
    fakeProcessManager.addCommands(const <FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>['xcrun', 'xcodebuild', '-version'],
        exception: ProcessException(xcodebuild, <String>['-version']),
      ),
    ]);

    expect(xcodeProjectInterpreter.versionText, isNull);
  });

  testWithoutContext('xcodebuild versionText returns formatted version text', () {
    fakeProcessManager.addCommands(const <FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>['xcrun', 'xcodebuild', '-version'],
        stdout: 'Xcode 8.3.3\nBuild version 8E3004b',
      ),
    ]);

    expect(xcodeProjectInterpreter.versionText, 'Xcode 8.3.3, Build version 8E3004b');
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext('xcodebuild versionText handles Xcode version string with unexpected format', () {
    fakeProcessManager.addCommands(const <FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>['xcrun', 'xcodebuild', '-version'],
        stdout: 'Xcode Ultra5000\nBuild version 8E3004b',
      ),
    ]);

    expect(xcodeProjectInterpreter.versionText, 'Xcode Ultra5000, Build version 8E3004b');
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext('xcodebuild version parts can be parsed', () {
    fakeProcessManager.addCommands(const <FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>['xcrun', 'xcodebuild', '-version'],
        stdout: 'Xcode 11.4.1\nBuild version 11N111s',
      ),
    ]);

    expect(xcodeProjectInterpreter.version, Version(11, 4, 1));
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext('xcodebuild minor and patch version default to 0', () {
    fakeProcessManager.addCommands(const <FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>['xcrun', 'xcodebuild', '-version'],
        stdout: 'Xcode 11\nBuild version 11N111s',
      ),
    ]);

    expect(xcodeProjectInterpreter.version, Version(11, 0, 0));
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext('xcodebuild version parts is null when version has unexpected format', () {
    fakeProcessManager.addCommands(const <FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>['xcrun', 'xcodebuild', '-version'],
        stdout: 'Xcode Ultra5000\nBuild version 8E3004b',
      ),
    ]);
    expect(xcodeProjectInterpreter.version, isNull);
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext('xcodebuild isInstalled is false when not on MacOS', () {
    final Platform platform = FakePlatform(operatingSystem: 'notMacOS');
    xcodeProjectInterpreter = XcodeProjectInterpreter(
      logger: logger,
      fileSystem: fileSystem,
      platform: platform,
      processManager: fakeProcessManager,
      usage: TestUsage(),
    );
    fileSystem.file(xcodebuild).deleteSync();

    expect(xcodeProjectInterpreter.isInstalled, isFalse);
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext('xcodebuild isInstalled is false when xcodebuild does not exist', () {
    fileSystem.file(xcodebuild).deleteSync();

    expect(xcodeProjectInterpreter.isInstalled, isFalse);
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext(
      'xcodebuild isInstalled is false when Xcode is not fully installed', () {
    fakeProcessManager.addCommands(const <FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>['xcrun', 'xcodebuild', '-version'],
        stdout: "xcode-select: error: tool 'xcodebuild' requires Xcode, "
            "but active developer directory '/Library/Developer/CommandLineTools' "
            'is a command line tools instance',
        exitCode: 1,
      ),
    ]);

    expect(xcodeProjectInterpreter.isInstalled, isFalse);
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext('xcodebuild isInstalled is false when version has unexpected format', () {
    fakeProcessManager.addCommands(const <FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>['xcrun', 'xcodebuild', '-version'],
        stdout: 'Xcode Ultra5000\nBuild version 8E3004b',
      ),
    ]);

    expect(xcodeProjectInterpreter.isInstalled, isFalse);
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext('xcodebuild isInstalled is true when version has expected format', () {
    fakeProcessManager.addCommands(const <FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>['xcrun', 'xcodebuild', '-version'],
        stdout: 'Xcode 8.3.3\nBuild version 8E3004b',
      ),
    ]);

    expect(xcodeProjectInterpreter.isInstalled, isTrue);
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext('xcrun runs natively on arm64', () {
    fakeProcessManager.addCommands(const <FakeCommand>[
      kWhichSysctlCommand,
      kARMCheckCommand,
    ]);

    expect(xcodeProjectInterpreter.xcrunCommand(), <String>[
      '/usr/bin/arch',
      '-arm64e',
      'xcrun',
    ]);
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testUsingContext('xcodebuild build settings is empty when xcodebuild failed to get the build settings', () async {
    platform.environment = const <String, String>{};

    fakeProcessManager.addCommands(<FakeCommand>[
      kWhichSysctlCommand,
      const FakeCommand(
        command: <String>[
          'sysctl',
          'hw.optional.arm64',
        ],
        exitCode: 1,
      ),
      FakeCommand(
        command: <String>[
          'xcrun',
          'xcodebuild',
          '-project',
          '/',
          '-scheme',
          'Free',
          '-destination',
          'id=123',
          '-showBuildSettings',
          'BUILD_DIR=${fileSystem.path.absolute('build', 'ios')}',
        ],
        exitCode: 1,
      ),
    ]);

    expect(
        await xcodeProjectInterpreter.getBuildSettings('', buildContext: const XcodeProjectBuildContext(deviceId: '123', scheme: 'Free')),
        const <String, String>{});
    expect(fakeProcessManager, hasNoRemainingExpectations);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => FakeProcessManager.any(),
  });

  testUsingContext('build settings passes in the simulator SDK', () async {
    platform.environment = const <String, String>{};

    fakeProcessManager.addCommands(<FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>[
          'xcrun',
          'xcodebuild',
          '-project',
          '/',
          '-sdk',
          'iphonesimulator',
          '-destination',
          'generic/platform=iOS Simulator',
          '-showBuildSettings',
          'BUILD_DIR=${fileSystem.path.absolute('build', 'ios')}',
        ],
        exitCode: 1,
      ),
    ]);

    expect(
      await xcodeProjectInterpreter.getBuildSettings(
        '',
        buildContext: const XcodeProjectBuildContext(environmentType: EnvironmentType.simulator),
      ),
      const <String, String>{},
    );
    expect(fakeProcessManager, hasNoRemainingExpectations);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => FakeProcessManager.any(),
  });

  testUsingContext('build settings accepts an empty scheme', () async {
    platform.environment = const <String, String>{};

    fakeProcessManager.addCommands(<FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>[
          'xcrun',
          'xcodebuild',
          '-project',
          '/',
          '-destination',
          'generic/platform=iOS',
          '-showBuildSettings',
          'BUILD_DIR=${fileSystem.path.absolute('build', 'ios')}',
        ],
        exitCode: 1,
      ),
    ]);

    expect(await xcodeProjectInterpreter.getBuildSettings('', buildContext: const XcodeProjectBuildContext()),
        const <String, String>{});
    expect(fakeProcessManager, hasNoRemainingExpectations);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => FakeProcessManager.any(),
  });

  testUsingContext('xcodebuild build settings contains Flutter Xcode environment variables', () async {
    platform.environment = const <String, String>{
      'FLUTTER_XCODE_CODE_SIGN_STYLE': 'Manual',
      'FLUTTER_XCODE_ARCHS': 'arm64'
    };
    fakeProcessManager.addCommands(<FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>[
          'xcrun',
          'xcodebuild',
          '-project',
          fileSystem.path.separator,
          '-scheme',
          'Free',
          '-destination',
          'generic/platform=iOS',
          '-showBuildSettings',
          'BUILD_DIR=${fileSystem.path.absolute('build', 'ios')}',
          'CODE_SIGN_STYLE=Manual',
          'ARCHS=arm64'
        ],
      ),
    ]);
    expect(
        await xcodeProjectInterpreter.getBuildSettings('', buildContext: const XcodeProjectBuildContext(scheme: 'Free')),
        const <String, String>{});
    expect(fakeProcessManager, hasNoRemainingExpectations);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => FakeProcessManager.any(),
  });

  testWithoutContext('xcodebuild clean contains Flutter Xcode environment variables', () async {
    platform.environment = const <String, String>{
      'FLUTTER_XCODE_CODE_SIGN_STYLE': 'Manual',
      'FLUTTER_XCODE_ARCHS': 'arm64'
    };

    fakeProcessManager.addCommands(const <FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>[
          'xcrun',
          'xcodebuild',
          '-workspace',
          'workspace_path',
          '-scheme',
          'Free',
          '-quiet',
          'clean',
          'CODE_SIGN_STYLE=Manual',
          'ARCHS=arm64'
        ],
      ),
    ]);

    await xcodeProjectInterpreter.cleanWorkspace('workspace_path', 'Free');
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext('xcodebuild -list getInfo returns something when xcodebuild -list succeeds', () async {
    const String workingDirectory = '/';
    fakeProcessManager.addCommands(const <FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>['xcrun', 'xcodebuild', '-list'],
      ),
    ]);

    final XcodeProjectInterpreter xcodeProjectInterpreter = XcodeProjectInterpreter(
      logger: logger,
      fileSystem: fileSystem,
      platform: platform,
      processManager: fakeProcessManager,
      usage: TestUsage(),
    );

    expect(await xcodeProjectInterpreter.getInfo(workingDirectory), isNotNull);
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext('xcodebuild -list getInfo throws a tool exit when it is unable to find a project', () async {
    const String workingDirectory = '/';
    const String stderr = 'Useful Xcode failure message about missing project.';

    fakeProcessManager.addCommands(const <FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>['xcrun', 'xcodebuild', '-list'],
        exitCode: 66,
        stderr: stderr,
      ),
    ]);

    final XcodeProjectInterpreter xcodeProjectInterpreter = XcodeProjectInterpreter(
      logger: logger,
      fileSystem: fileSystem,
      platform: platform,
      processManager: fakeProcessManager,
      usage: TestUsage(),
    );

    expect(() => xcodeProjectInterpreter.getInfo(workingDirectory), throwsToolExit(message: stderr));
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext('xcodebuild -list getInfo throws a tool exit when project is corrupted', () async {
    const String workingDirectory = '/';
    const String stderr = 'Useful Xcode failure message about corrupted project.';

    fakeProcessManager.addCommands(const <FakeCommand>[
      kWhichSysctlCommand,
      kx64CheckCommand,
      FakeCommand(
        command: <String>['xcrun', 'xcodebuild', '-list'],
        exitCode: 74,
        stderr: stderr,
      ),
    ]);

    final XcodeProjectInterpreter xcodeProjectInterpreter = XcodeProjectInterpreter(
      logger: logger,
      fileSystem: fileSystem,
      platform: platform,
      processManager: fakeProcessManager,
      usage: TestUsage(),
    );

    expect(() => xcodeProjectInterpreter.getInfo(workingDirectory), throwsToolExit(message: stderr));
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testWithoutContext('Xcode project properties from default project can be parsed', () {
    const String output = '''
Information about project "Runner":
    Targets:
        Runner

    Build Configurations:
        Debug
        Release

    If no build configuration is specified and -scheme is not passed then "Release" is used.

    Schemes:
        Runner

''';
    final XcodeProjectInfo info = XcodeProjectInfo.fromXcodeBuildOutput(output, logger);
    expect(info.targets, <String>['Runner']);
    expect(info.schemes, <String>['Runner']);
    expect(info.buildConfigurations, <String>['Debug', 'Release']);
  });

  testWithoutContext('Xcode project properties from project with custom schemes can be parsed', () {
    const String output = '''
Information about project "Runner":
    Targets:
        Runner

    Build Configurations:
        Debug (Free)
        Debug (Paid)
        Release (Free)
        Release (Paid)

    If no build configuration is specified and -scheme is not passed then "Release (Free)" is used.

    Schemes:
        Free
        Paid

''';
    final XcodeProjectInfo info = XcodeProjectInfo.fromXcodeBuildOutput(output, logger);
    expect(info.targets, <String>['Runner']);
    expect(info.schemes, <String>['Free', 'Paid']);
    expect(info.buildConfigurations, <String>['Debug (Free)', 'Debug (Paid)', 'Release (Free)', 'Release (Paid)']);
  });

  testWithoutContext('expected scheme for non-flavored build is Runner', () {
    expect(XcodeProjectInfo.expectedSchemeFor(BuildInfo.debug), 'Runner');
    expect(XcodeProjectInfo.expectedSchemeFor(BuildInfo.profile), 'Runner');
    expect(XcodeProjectInfo.expectedSchemeFor(BuildInfo.release), 'Runner');
  });

  testWithoutContext('expected build configuration for non-flavored build is derived from BuildMode', () {
    expect(XcodeProjectInfo.expectedBuildConfigurationFor(BuildInfo.debug, 'Runner'), 'Debug');
    expect(XcodeProjectInfo.expectedBuildConfigurationFor(BuildInfo.profile, 'Runner'), 'Profile');
    expect(XcodeProjectInfo.expectedBuildConfigurationFor(BuildInfo.release, 'Runner'), 'Release');
  });

  testWithoutContext('expected scheme for flavored build is the title-cased flavor', () {
    expect(XcodeProjectInfo.expectedSchemeFor(const BuildInfo(BuildMode.debug, 'hello', treeShakeIcons: false)), 'Hello');
    expect(XcodeProjectInfo.expectedSchemeFor(const BuildInfo(BuildMode.profile, 'HELLO', treeShakeIcons: false)), 'HELLO');
    expect(XcodeProjectInfo.expectedSchemeFor(const BuildInfo(BuildMode.release, 'Hello', treeShakeIcons: false)), 'Hello');
  });
  testWithoutContext('expected build configuration for flavored build is Mode-Flavor', () {
    expect(XcodeProjectInfo.expectedBuildConfigurationFor(const BuildInfo(BuildMode.debug, 'hello', treeShakeIcons: false), 'Hello'), 'Debug-Hello');
    expect(XcodeProjectInfo.expectedBuildConfigurationFor(const BuildInfo(BuildMode.profile, 'HELLO', treeShakeIcons: false), 'Hello'), 'Profile-Hello');
    expect(XcodeProjectInfo.expectedBuildConfigurationFor(const BuildInfo(BuildMode.release, 'Hello', treeShakeIcons: false), 'Hello'), 'Release-Hello');
  });

  testWithoutContext('scheme for default project is Runner', () {
    final XcodeProjectInfo info = XcodeProjectInfo(<String>['Runner'], <String>['Debug', 'Release'], <String>['Runner'], logger);

    expect(info.schemeFor(BuildInfo.debug), 'Runner');
    expect(info.schemeFor(BuildInfo.profile), 'Runner');
    expect(info.schemeFor(BuildInfo.release), 'Runner');
    expect(info.schemeFor(const BuildInfo(BuildMode.debug, 'unknown', treeShakeIcons: false)), isNull);
  });

  testWithoutContext('build configuration for default project is matched against BuildMode', () {
    final XcodeProjectInfo info = XcodeProjectInfo(<String>['Runner'], <String>['Debug', 'Profile', 'Release'], <String>['Runner'], logger);

    expect(info.buildConfigurationFor(BuildInfo.debug, 'Runner'), 'Debug');
    expect(info.buildConfigurationFor(BuildInfo.profile, 'Runner'), 'Profile');
    expect(info.buildConfigurationFor(BuildInfo.release, 'Runner'), 'Release');
  });

  testWithoutContext('scheme for project with custom schemes is matched against flavor', () {
    final XcodeProjectInfo info = XcodeProjectInfo(
      <String>['Runner'],
      <String>['Debug (Free)', 'Debug (Paid)', 'Release (Free)', 'Release (Paid)'],
      <String>['Free', 'Paid'],
      logger,
    );

    expect(info.schemeFor(const BuildInfo(BuildMode.debug, 'free', treeShakeIcons: false)), 'Free');
    expect(info.schemeFor(const BuildInfo(BuildMode.profile, 'Free', treeShakeIcons: false)), 'Free');
    expect(info.schemeFor(const BuildInfo(BuildMode.release, 'paid', treeShakeIcons: false)), 'Paid');
    expect(info.schemeFor(BuildInfo.debug), isNull);
    expect(info.schemeFor(const BuildInfo(BuildMode.debug, 'unknown', treeShakeIcons: false)), isNull);
  });

  testWithoutContext('reports default scheme error and exit', () {
    final XcodeProjectInfo defaultInfo = XcodeProjectInfo(
      <String>[],
      <String>[],
      <String>['Runner'],
      logger,
    );

    expect(
      defaultInfo.reportFlavorNotFoundAndExit,
      throwsToolExit(
        message: 'The Xcode project does not define custom schemes. You cannot use the --flavor option.'
      ),
    );
  });

  testWithoutContext('reports custom scheme error and exit', () {
    final XcodeProjectInfo info = XcodeProjectInfo(
      <String>[],
      <String>[],
      <String>['Free', 'Paid'],
      logger,
    );

    expect(
      info.reportFlavorNotFoundAndExit,
      throwsToolExit(
        message: 'You must specify a --flavor option to select one of the available schemes.'
      ),
    );
  });

  testWithoutContext('build configuration for project with custom schemes is matched against BuildMode and flavor', () {
    final XcodeProjectInfo info = XcodeProjectInfo(
      <String>['Runner'],
      <String>['debug (free)', 'Debug paid', 'profile - Free', 'Profile-Paid', 'release - Free', 'Release-Paid'],
      <String>['Free', 'Paid'],
      logger,
    );

    expect(info.buildConfigurationFor(const BuildInfo(BuildMode.debug, 'free', treeShakeIcons: false), 'Free'), 'debug (free)');
    expect(info.buildConfigurationFor(const BuildInfo(BuildMode.debug, 'Paid', treeShakeIcons: false), 'Paid'), 'Debug paid');
    expect(info.buildConfigurationFor(const BuildInfo(BuildMode.profile, 'FREE', treeShakeIcons: false), 'Free'), 'profile - Free');
    expect(info.buildConfigurationFor(const BuildInfo(BuildMode.release, 'paid', treeShakeIcons: false), 'Paid'), 'Release-Paid');
  });

  testWithoutContext('build configuration for project with inconsistent naming is null', () {
    final XcodeProjectInfo info = XcodeProjectInfo(
      <String>['Runner'],
      <String>['Debug-F', 'Dbg Paid', 'Rel Free', 'Release Full'],
      <String>['Free', 'Paid'],
      logger,
    );
    expect(info.buildConfigurationFor(const BuildInfo(BuildMode.debug, 'Free', treeShakeIcons: false), 'Free'), null);
    expect(info.buildConfigurationFor(const BuildInfo(BuildMode.profile, 'Free', treeShakeIcons: false), 'Free'), null);
    expect(info.buildConfigurationFor(const BuildInfo(BuildMode.release, 'Paid', treeShakeIcons: false), 'Paid'), null);
  });
 group('environmentVariablesAsXcodeBuildSettings', () {
    FakePlatform platform;

    setUp(() {
      platform = FakePlatform();
    });

    testWithoutContext('environment variables as Xcode build settings', () {
      platform.environment = const <String, String>{
        'Ignored': 'Bogus',
        'FLUTTER_NOT_XCODE': 'Bogus',
        'FLUTTER_XCODE_CODE_SIGN_STYLE': 'Manual',
        'FLUTTER_XCODE_ARCHS': 'arm64'
      };
      final List<String> environmentVariablesAsBuildSettings = environmentVariablesAsXcodeBuildSettings(platform);
      expect(environmentVariablesAsBuildSettings, <String>['CODE_SIGN_STYLE=Manual', 'ARCHS=arm64']);
    });
  });

  group('updateGeneratedXcodeProperties', () {
    Artifacts localIosArtifacts;
    FakePlatform macOS;
    FileSystem fs;

    setUp(() {
      fs = MemoryFileSystem.test();
      localIosArtifacts = Artifacts.test(localEngine: 'out/ios_profile_arm');
      macOS = FakePlatform(operatingSystem: 'macos');
      fs.file(xcodebuild).createSync(recursive: true);
    });

    group('arm simulator', () {
      FakeProcessManager fakeProcessManager;
      XcodeProjectInterpreter xcodeProjectInterpreter;

      setUp(() {
        fakeProcessManager = FakeProcessManager.empty();
        xcodeProjectInterpreter = XcodeProjectInterpreter.test(processManager: fakeProcessManager);
      });

      testUsingContext('does not exclude arm64 simulator when supported by all plugins', () async {
        const BuildInfo buildInfo = BuildInfo.debug;
        final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
        final Directory podXcodeProject = project.ios.hostAppRoot.childDirectory('Pods').childDirectory('Pods.xcodeproj')
          ..createSync(recursive: true);

        final String buildDirectory = fileSystem.path.absolute('build', 'ios');
        fakeProcessManager.addCommands(<FakeCommand>[
          kWhichSysctlCommand,
          kARMCheckCommand,
          FakeCommand(
            command: <String>[
              '/usr/bin/arch',
              '-arm64e',
              'xcrun',
              'xcodebuild',
              '-alltargets',
              '-sdk',
              'iphonesimulator',
              '-project',
              podXcodeProject.path,
              '-showBuildSettings',
              'BUILD_DIR=$buildDirectory',
              'OBJROOT=$buildDirectory',
            ],
            stdout: '''
Build settings for action build and target plugin1:
    ENABLE_BITCODE = NO;
    EXCLUDED_ARCHS = i386;
    INFOPLIST_FILE = Runner/Info.plist;
    UNRELATED_BUILD_SETTING = arm64;

Build settings for action build and target plugin2:
    ENABLE_BITCODE = NO;
    EXCLUDED_ARCHS = i386;
    INFOPLIST_FILE = Runner/Info.plist;
    UNRELATED_BUILD_SETTING = arm64;
				'''
          ),
        ]);
        await updateGeneratedXcodeProperties(
          project: project,
          buildInfo: buildInfo,
        );

        final File config = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
        expect(config.readAsStringSync(), contains('EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386\n'));
        expect(fakeProcessManager, hasNoRemainingExpectations);
      }, overrides: <Type, Generator>{
        Artifacts: () => localIosArtifacts,
        Platform: () => macOS,
        FileSystem: () => fs,
        ProcessManager: () => fakeProcessManager,
        XcodeProjectInterpreter: () => xcodeProjectInterpreter,
      });

      testUsingContext('excludes arm64 simulator when build setting fetch fails', () async {
        const BuildInfo buildInfo = BuildInfo.debug;
        final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
        final Directory podXcodeProject = project.ios.hostAppRoot.childDirectory('Pods').childDirectory('Pods.xcodeproj')
          ..createSync(recursive: true);

        final String buildDirectory = fileSystem.path.absolute('build', 'ios');
        fakeProcessManager.addCommands(<FakeCommand>[
          kWhichSysctlCommand,
          kARMCheckCommand,
          FakeCommand(
              command: <String>[
                '/usr/bin/arch',
                '-arm64e',
                'xcrun',
                'xcodebuild',
                '-alltargets',
                '-sdk',
                'iphonesimulator',
                '-project',
                podXcodeProject.path,
                '-showBuildSettings',
                'BUILD_DIR=$buildDirectory',
                'OBJROOT=$buildDirectory',
              ],
              exitCode: 1,
          ),
        ]);
        await updateGeneratedXcodeProperties(
          project: project,
          buildInfo: buildInfo,
        );

        final File config = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
        expect(config.readAsStringSync(), contains('EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386 arm64\n'));
        expect(fakeProcessManager, hasNoRemainingExpectations);
      }, overrides: <Type, Generator>{
        Artifacts: () => localIosArtifacts,
        Platform: () => macOS,
        FileSystem: () => fs,
        ProcessManager: () => fakeProcessManager,
        XcodeProjectInterpreter: () => xcodeProjectInterpreter,
      });

      testUsingContext('excludes arm64 simulator when unsupported by plugins', () async {
        const BuildInfo buildInfo = BuildInfo.debug;
        final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
        final Directory podXcodeProject = project.ios.hostAppRoot.childDirectory('Pods').childDirectory('Pods.xcodeproj')
          ..createSync(recursive: true);

        final String buildDirectory = fileSystem.path.absolute('build', 'ios');
        fakeProcessManager.addCommands(<FakeCommand>[
          kWhichSysctlCommand,
          kARMCheckCommand,
          FakeCommand(
              command: <String>[
                '/usr/bin/arch',
                '-arm64e',
                'xcrun',
                'xcodebuild',
                '-alltargets',
                '-sdk',
                'iphonesimulator',
                '-project',
                podXcodeProject.path,
                '-showBuildSettings',
                'BUILD_DIR=$buildDirectory',
                'OBJROOT=$buildDirectory',
              ],
              stdout: '''
Build settings for action build and target plugin1:
    ENABLE_BITCODE = NO;
    EXCLUDED_ARCHS = i386;
    INFOPLIST_FILE = Runner/Info.plist;
    UNRELATED_BUILD_SETTING = arm64;

Build settings for action build and target plugin2:
    ENABLE_BITCODE = NO;
    EXCLUDED_ARCHS = i386 arm64;
    INFOPLIST_FILE = Runner/Info.plist;
    UNRELATED_BUILD_SETTING = arm64;
				'''
          ),
        ]);
        await updateGeneratedXcodeProperties(
          project: project,
          buildInfo: buildInfo,
        );

        final File config = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
        expect(config.readAsStringSync(), contains('EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386 arm64\n'));
        expect(fakeProcessManager, hasNoRemainingExpectations);
      }, overrides: <Type, Generator>{
        Artifacts: () => localIosArtifacts,
        Platform: () => macOS,
        FileSystem: () => fs,
        ProcessManager: () => fakeProcessManager,
        XcodeProjectInterpreter: () => xcodeProjectInterpreter,
      });
    });

    void testUsingOsxContext(String description, dynamic Function() testMethod) {
      testUsingContext(description, testMethod, overrides: <Type, Generator>{
        Artifacts: () => localIosArtifacts,
        Platform: () => macOS,
        FileSystem: () => fs,
        ProcessManager: () => FakeProcessManager.any(),
      });
    }

    testUsingOsxContext('sets ARCHS=armv7 when armv7 local iOS engine is set', () async {
      const BuildInfo buildInfo = BuildInfo.debug;
      final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
      await updateGeneratedXcodeProperties(
        project: project,
        buildInfo: buildInfo,
      );

      final File config = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
      expect(config.existsSync(), isTrue);

      final String contents = config.readAsStringSync();
      expect(contents.contains('ARCHS=armv7'), isTrue);
      expect(contents.contains('EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386'), isTrue);

      final File buildPhaseScript = fs.file('path/to/project/ios/Flutter/flutter_export_environment.sh');
      expect(buildPhaseScript.existsSync(), isTrue);

      final String buildPhaseScriptContents = buildPhaseScript.readAsStringSync();
      expect(buildPhaseScriptContents.contains('ARCHS=armv7'), isTrue);
      expect(buildPhaseScriptContents.contains('EXCLUDED_ARCHS'), isFalse);
    });

    testUsingContext('sets ARCHS=arm64 when arm64 local host engine is set', () async {
      const BuildInfo buildInfo = BuildInfo.debug;
      final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
      await updateGeneratedXcodeProperties(
        project: project,
        buildInfo: buildInfo,
        useMacOSConfig: true,
      );

      final File config = fs.file('path/to/project/macos/Flutter/ephemeral/Flutter-Generated.xcconfig');
      expect(config.existsSync(), isTrue);

      final String contents = config.readAsStringSync();
      expect(contents.contains('ARCHS=arm64\n'), isTrue);

      final File buildPhaseScript = fs.file('path/to/project/macos/Flutter/ephemeral/flutter_export_environment.sh');
      expect(buildPhaseScript.existsSync(), isTrue);

      final String buildPhaseScriptContents = buildPhaseScript.readAsStringSync();
      expect(buildPhaseScriptContents.contains('export "ARCHS=arm64"'), isTrue);
    }, overrides: <Type, Generator>{
      Artifacts: () => Artifacts.test(localEngine: 'out/host_profile_arm64'),
      Platform: () => macOS,
      FileSystem: () => fs,
      ProcessManager: () => FakeProcessManager.any(),
    });

    testUsingContext('sets ARCHS=x86_64 when x64 local host engine is set', () async {
      const BuildInfo buildInfo = BuildInfo.debug;
      final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
      await updateGeneratedXcodeProperties(
        project: project,
        buildInfo: buildInfo,
        useMacOSConfig: true,
      );

      final File config = fs.file('path/to/project/macos/Flutter/ephemeral/Flutter-Generated.xcconfig');
      expect(config.existsSync(), isTrue);

      final String contents = config.readAsStringSync();
      expect(contents.contains('ARCHS=x86_64\n'), isTrue);

      final File buildPhaseScript = fs.file('path/to/project/macos/Flutter/ephemeral/flutter_export_environment.sh');
      expect(buildPhaseScript.existsSync(), isTrue);

      final String buildPhaseScriptContents = buildPhaseScript.readAsStringSync();
      expect(buildPhaseScriptContents.contains('export "ARCHS=x86_64"'), isTrue);
    }, overrides: <Type, Generator>{
      Artifacts: () => Artifacts.test(localEngine: 'out/host_profile'),
      Platform: () => macOS,
      FileSystem: () => fs,
      ProcessManager: () => FakeProcessManager.any(),
    });

    testUsingOsxContext('does not exclude arm64 simulator when there are no plugins', () async {
      const BuildInfo buildInfo = BuildInfo.debug;
      final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
      await updateGeneratedXcodeProperties(
        project: project,
        buildInfo: buildInfo,
      );

      final File config = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
      expect(config.readAsStringSync(), contains('EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386\n'));

      final File buildPhaseScript = fs.file('path/to/project/ios/Flutter/flutter_export_environment.sh');
      expect(buildPhaseScript.readAsStringSync(), isNot(contains('EXCLUDED_ARCHS')));
    });

    testUsingOsxContext('sets TRACK_WIDGET_CREATION=true when trackWidgetCreation is true', () async {
      const BuildInfo buildInfo = BuildInfo(BuildMode.debug, null, trackWidgetCreation: true, treeShakeIcons: false);
      final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
      await updateGeneratedXcodeProperties(
        project: project,
        buildInfo: buildInfo,
      );

      final File config = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
      expect(config.existsSync(), isTrue);

      final String contents = config.readAsStringSync();
      expect(contents.contains('TRACK_WIDGET_CREATION=true'), isTrue);

      final File buildPhaseScript = fs.file('path/to/project/ios/Flutter/flutter_export_environment.sh');
      expect(buildPhaseScript.existsSync(), isTrue);

      final String buildPhaseScriptContents = buildPhaseScript.readAsStringSync();
      expect(buildPhaseScriptContents.contains('TRACK_WIDGET_CREATION=true'), isTrue);
    });

    testUsingOsxContext('does not set TRACK_WIDGET_CREATION when trackWidgetCreation is false', () async {
      const BuildInfo buildInfo = BuildInfo.debug;
      final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
      await updateGeneratedXcodeProperties(
        project: project,
        buildInfo: buildInfo,
      );

      final File config = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
      expect(config.existsSync(), isTrue);

      final String contents = config.readAsStringSync();
      expect(contents.contains('TRACK_WIDGET_CREATION=true'), isFalse);

      final File buildPhaseScript = fs.file('path/to/project/ios/Flutter/flutter_export_environment.sh');
      expect(buildPhaseScript.existsSync(), isTrue);

      final String buildPhaseScriptContents = buildPhaseScript.readAsStringSync();
      expect(buildPhaseScriptContents.contains('TRACK_WIDGET_CREATION=true'), isFalse);
    });

    group('sim local engine', () {
      testUsingContext('sets ARCHS=x86_64 when x86 sim local engine is set', () async {
        const BuildInfo buildInfo = BuildInfo.debug;
        final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
        await updateGeneratedXcodeProperties(
          project: project,
          buildInfo: buildInfo,
        );

        final File config = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
        expect(config.existsSync(), isTrue);

        final String contents = config.readAsStringSync();
        expect(contents.contains('ARCHS=x86_64'), isTrue);

        final File buildPhaseScript = fs.file('path/to/project/ios/Flutter/flutter_export_environment.sh');
        expect(buildPhaseScript.existsSync(), isTrue);

        final String buildPhaseScriptContents = buildPhaseScript.readAsStringSync();
        expect(buildPhaseScriptContents.contains('ARCHS=x86_64'), isTrue);
      }, overrides: <Type, Generator>{
        Artifacts: () => Artifacts.test(localEngine: 'out/ios_debug_sim_unopt'),
        Platform: () => macOS,
        FileSystem: () => fs,
        ProcessManager: () => FakeProcessManager.any(),
      });

      testUsingContext('sets ARCHS=arm64 when arm64 sim local engine is set', () async {
        const BuildInfo buildInfo = BuildInfo.debug;
        final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
        await updateGeneratedXcodeProperties(
          project: project,
          buildInfo: buildInfo,
        );

        final File config = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
        expect(config.existsSync(), isTrue);

        final String contents = config.readAsStringSync();
        expect(contents.contains('ARCHS=arm64'), isTrue);

        final File buildPhaseScript = fs.file('path/to/project/ios/Flutter/flutter_export_environment.sh');
        expect(buildPhaseScript.existsSync(), isTrue);

        final String buildPhaseScriptContents = buildPhaseScript.readAsStringSync();
        expect(buildPhaseScriptContents.contains('ARCHS=arm64'), isTrue);
      }, overrides: <Type, Generator>{
        Artifacts: () => Artifacts.test(localEngine: 'out/ios_debug_sim_arm64'),
        Platform: () => macOS,
        FileSystem: () => fs,
        ProcessManager: () => FakeProcessManager.any(),
      });
    });

    group('armv7 local engine', () {
      Artifacts localArtifacts;

      setUp(() {
        localArtifacts = Artifacts.test(localEngine: 'out/ios_profile');
      });

      testUsingContext('sets ARCHS=armv7 when armv7 local engine is set', () async {
        const BuildInfo buildInfo = BuildInfo.debug;

        final FlutterProject project = FlutterProject.fromDirectoryTest(fs.directory('path/to/project'));
        await updateGeneratedXcodeProperties(
          project: project,
          buildInfo: buildInfo,
        );

        final File config = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
        expect(config.existsSync(), isTrue);

        final String contents = config.readAsStringSync();
        expect(contents.contains('ARCHS=arm64'), isTrue);
      }, overrides: <Type, Generator>{
        Artifacts: () => localArtifacts,
        Platform: () => macOS,
        FileSystem: () => fs,
        ProcessManager: () => FakeProcessManager.any(),
      });
    });

    String propertyFor(String key, File file) {
      final List<String> properties = file
          .readAsLinesSync()
          .where((String line) => line.startsWith('$key='))
          .map((String line) => line.split('=')[1])
          .toList();
      return properties.isEmpty ? null : properties.first;
    }

    Future<void> checkBuildVersion({
      String manifestString,
      BuildInfo buildInfo,
      String expectedBuildName,
      String expectedBuildNumber,
    }) async {
      final File manifestFile = fs.file('path/to/project/pubspec.yaml');
      manifestFile.createSync(recursive: true);
      manifestFile.writeAsStringSync(manifestString);

      await updateGeneratedXcodeProperties(
        project: FlutterProject.fromDirectoryTest(fs.directory('path/to/project')),
        buildInfo: buildInfo,
      );

      final File localPropertiesFile = fs.file('path/to/project/ios/Flutter/Generated.xcconfig');
      expect(propertyFor('FLUTTER_BUILD_NAME', localPropertiesFile), expectedBuildName);
      expect(propertyFor('FLUTTER_BUILD_NUMBER', localPropertiesFile), expectedBuildNumber);
      expect(propertyFor('FLUTTER_BUILD_NUMBER', localPropertiesFile), isNotNull);
    }

    testUsingOsxContext('extract build name and number from pubspec.yaml', () async {
      const String manifest = '''
name: test
version: 1.0.0+1
dependencies:
  flutter:
    sdk: flutter
flutter:
''';

      const BuildInfo buildInfo = BuildInfo(BuildMode.release, null, treeShakeIcons: false);
      await checkBuildVersion(
        manifestString: manifest,
        buildInfo: buildInfo,
        expectedBuildName: '1.0.0',
        expectedBuildNumber: '1',
      );
    });

    testUsingOsxContext('extract build name from pubspec.yaml', () async {
      const String manifest = '''
name: test
version: 1.0.0
dependencies:
  flutter:
    sdk: flutter
flutter:
''';
      const BuildInfo buildInfo = BuildInfo(BuildMode.release, null, treeShakeIcons: false);
      await checkBuildVersion(
        manifestString: manifest,
        buildInfo: buildInfo,
        expectedBuildName: '1.0.0',
        expectedBuildNumber: '1.0.0',
      );
    });

    testUsingOsxContext('allow build info to override build name', () async {
      const String manifest = '''
name: test
version: 1.0.0+1
dependencies:
  flutter:
    sdk: flutter
flutter:
''';
      const BuildInfo buildInfo = BuildInfo(BuildMode.release, null, buildName: '1.0.2', treeShakeIcons: false);
      await checkBuildVersion(
        manifestString: manifest,
        buildInfo: buildInfo,
        expectedBuildName: '1.0.2',
        expectedBuildNumber: '1',
      );
    });

    testUsingOsxContext('allow build info to override build name with build number fallback', () async {
      const String manifest = '''
name: test
version: 1.0.0
dependencies:
  flutter:
    sdk: flutter
flutter:
''';
      const BuildInfo buildInfo = BuildInfo(BuildMode.release, null, buildName: '1.0.2', treeShakeIcons: false);
      await checkBuildVersion(
        manifestString: manifest,
        buildInfo: buildInfo,
        expectedBuildName: '1.0.2',
        expectedBuildNumber: '1.0.2',
      );
    });

    testUsingOsxContext('allow build info to override build number', () async {
      const String manifest = '''
name: test
version: 1.0.0+1
dependencies:
  flutter:
    sdk: flutter
flutter:
''';
      const BuildInfo buildInfo = BuildInfo(BuildMode.release, null, buildNumber: '3', treeShakeIcons: false);
      await checkBuildVersion(
        manifestString: manifest,
        buildInfo: buildInfo,
        expectedBuildName: '1.0.0',
        expectedBuildNumber: '3',
      );
    });

    testUsingOsxContext('allow build info to override build name and number', () async {
      const String manifest = '''
name: test
version: 1.0.0+1
dependencies:
  flutter:
    sdk: flutter
flutter:
''';
      const BuildInfo buildInfo = BuildInfo(BuildMode.release, null, buildName: '1.0.2', buildNumber: '3', treeShakeIcons: false);
      await checkBuildVersion(
        manifestString: manifest,
        buildInfo: buildInfo,
        expectedBuildName: '1.0.2',
        expectedBuildNumber: '3',
      );
    });

    testUsingOsxContext('allow build info to override build name and set number', () async {
      const String manifest = '''
name: test
version: 1.0.0
dependencies:
  flutter:
    sdk: flutter
flutter:
''';
      const BuildInfo buildInfo = BuildInfo(BuildMode.release, null, buildName: '1.0.2', buildNumber: '3', treeShakeIcons: false);
      await checkBuildVersion(
        manifestString: manifest,
        buildInfo: buildInfo,
        expectedBuildName: '1.0.2',
        expectedBuildNumber: '3',
      );
    });

    testUsingOsxContext('allow build info to set build name and number', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
''';
      const BuildInfo buildInfo = BuildInfo(BuildMode.release, null, buildName: '1.0.2', buildNumber: '3', treeShakeIcons: false);
      await checkBuildVersion(
        manifestString: manifest,
        buildInfo: buildInfo,
        expectedBuildName: '1.0.2',
        expectedBuildNumber: '3',
      );
    });

    testUsingOsxContext('default build name and number when version is missing', () async {
      const String manifest = '''
name: test
dependencies:
  flutter:
    sdk: flutter
flutter:
''';
      const BuildInfo buildInfo = BuildInfo(BuildMode.release, null, treeShakeIcons: false);
      await checkBuildVersion(
        manifestString: manifest,
        buildInfo: buildInfo,
        expectedBuildName: '1.0.0',
        expectedBuildNumber: '1',
      );
    });
  });
}
