// 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';

void main(List<String> arguments) {
  File? scriptOutputStreamFile;
  final String? scriptOutputStreamFileEnv = Platform.environment['SCRIPT_OUTPUT_STREAM_FILE'];
  if (scriptOutputStreamFileEnv != null && scriptOutputStreamFileEnv.isNotEmpty) {
    scriptOutputStreamFile = File(scriptOutputStreamFileEnv);
  }
  Context(
    arguments: arguments,
    environment: Platform.environment,
    scriptOutputStreamFile: scriptOutputStreamFile,
  ).run();
}

/// Container for script arguments and environment variables.
///
/// All interactions with the platform are broken into individual methods that
/// can be overridden in tests.
class Context {
  Context({required this.arguments, required this.environment, File? scriptOutputStreamFile}) {
    if (scriptOutputStreamFile != null) {
      scriptOutputStream = scriptOutputStreamFile.openSync(mode: FileMode.write);
    }
  }

  final Map<String, String> environment;
  final List<String> arguments;
  RandomAccessFile? scriptOutputStream;

  static const incompatibleErrorMessage =
      'Your Xcode project is incompatible with this version of Flutter. '
      'Run "rm -rf ios/Runner.xcodeproj" and "flutter create ." to regenerate.\n';

  void run() {
    if (arguments.isEmpty) {
      // Named entry points were introduced in Flutter v0.0.7.
      echoXcodeError(incompatibleErrorMessage);
      exit(-1);
    }

    final String subCommand = validateCommand(arguments[0]);
    final String? platformName = arguments.length < 2 ? null : arguments[1];
    final TargetPlatform platform = parsePlatform(platformName);
    switch (subCommand) {
      case 'build':
        buildApp(platform);
      case 'prepare':
        prepare(platform);
      case 'thin':
        // No-op, thinning is handled during the bundle asset assemble build target.
        break;
      case 'embed':
      case 'embed_and_thin':
        // Thinning is handled during the bundle asset assemble build target, so just embed.
        embedFlutterFrameworks(platform);
      case 'test_vm_service_bonjour_service':
        // Exposed for integration testing only.
        addVmServiceBonjourService();
    }
  }

  /// Validates the command argument matches one of the possible commands.
  /// Returns null if not.
  String validateCommand(String command) {
    switch (command) {
      case 'build':
      case 'prepare':
      case 'thin':
      case 'embed':
      case 'embed_and_thin':
      case 'test_vm_service_bonjour_service':
        return command;
      default:
        echoXcodeError(incompatibleErrorMessage);
        exit(-1);
    }
  }

  /// Converts the [platformName] argument to a [TargetPlatform]. If there is
  /// not a match, prints a warning and defaults to [TargetPlatform.ios].
  TargetPlatform parsePlatform(String? platformName) {
    switch (platformName) {
      case 'macos':
        return TargetPlatform.macos;
      case 'ios':
        return TargetPlatform.ios;
      default:
        echoXcodeWarning('Unrecognized platform: $platformName. Defaulting to iOS.');
        return TargetPlatform.ios;
    }
  }

  bool existsFile(String path) {
    final file = File(path);
    return file.existsSync();
  }

  Directory directoryFromPath(String path) => Directory(path);

  /// Run given command ([bin]) in a synchronous subprocess.
  ///
  /// If [allowFail] is true, an exception will not be thrown even if the process returns a
  /// non-zero exit code. Also, `error:` will not be prefixed to the output to prevent Xcode
  /// complication failures.
  ///
  /// If [skipErrorLog] is true, `stderr` from the process will not be output unless in [verbose]
  /// mode. If in [verbose], pipes `stderr` to `stdout`.
  ///
  /// Will throw [Exception] if the exit code is not 0.
  ProcessResult runSync(
    String bin,
    List<String> args, {
    bool verbose = false,
    bool allowFail = false,
    bool skipErrorLog = false,
    String? workingDirectory,
  }) {
    if (verbose) {
      print('♦ $bin ${args.join(' ')}');
    }
    final ProcessResult result = runSyncProcess(bin, args, workingDirectory: workingDirectory);
    if (verbose) {
      print((result.stdout as String).trim());
    }
    final String resultStderr = result.stderr.toString().trim();
    if (resultStderr.isNotEmpty) {
      final errorOutput = StringBuffer();
      if (!allowFail && result.exitCode != 0) {
        // "error:" prefix makes this show up as an Xcode compilation error.
        errorOutput.write('error: ');
      }
      errorOutput.write(resultStderr);
      if (skipErrorLog) {
        // Even if skipErrorLog, we still want to write to stdout if verbose.
        if (verbose) {
          echo(errorOutput.toString());
        }
      } else {
        echoError(errorOutput.toString());
      }
      // Stream stderr to the Flutter build process.
      // When in verbose mode, `echoError` above will show the logs. So only
      // stream if not in verbose mode to avoid duplicate logs.
      // Also, only stream if exitCode is 0 since errors are handled separately
      // by the tool on failure.
      // Also check for `skipErrorLog`, because some errors should not be printed
      // out. For example, on macOS 26, plutil reports NSBonjourServices key not
      // found as an error. However, logging it in non-verbose mode would be
      // confusing, since not having the key is one of the expected states.
      if (!verbose && exitCode == 0 && !skipErrorLog) {
        streamOutput(errorOutput.toString());
      }
    }
    if (!allowFail && result.exitCode != 0) {
      throw Exception('Command "$bin ${args.join(' ')}" exited with code ${result.exitCode}');
    }
    return result;
  }

  // TODO(hellohuanlin): Instead of using inheritance to stub the function in
  // the subclass, we should favor composition by injecting the dependencies.
  // See: https://github.com/flutter/flutter/issues/173133
  ProcessResult runSyncProcess(String bin, List<String> args, {String? workingDirectory}) {
    return Process.runSync(bin, args, workingDirectory: workingDirectory);
  }

  /// Log message to stderr.
  void echoError(String message) {
    stderr.writeln(message);
  }

  /// Log message to stderr.
  void echoXcodeError(String message) {
    stderr.writeln('error: $message');
  }

  /// Log message appended with `warning:` to stderr.
  /// This will display with a yellow warning icon in Xcode.
  void echoXcodeWarning(String message) {
    stderr.writeln('warning: $message');
  }

  /// Log message to stdout.
  void echo(String message) {
    stdout.write(message);
  }

  /// Exit the application with the given exit code.
  ///
  /// Exists to allow overriding in tests.
  Never exitApp(int code) {
    exit(code);
  }

  /// Return value from environment if it exists, else throw [Exception].
  String environmentEnsure(String key) {
    final String? value = environment[key];
    if (value == null) {
      throw Exception('Expected the environment variable "$key" to exist, but it was not found');
    }
    return value;
  }

  // When provided with a pipe by the host Flutter build process, output to the
  // pipe goes to stdout of the Flutter build process directly.
  void streamOutput(String output) {
    scriptOutputStream?.writeStringSync('$output\n');
  }

  /// Parses and normalizes the build mode (debug, profile, release).
  ///
  /// Uses `FLUTTER_BUILD_MODE` (uncommon) if set, otherwise uses `CONFIGURATION`.
  /// The `CONFIGURATION` may not match exactly since it can be named by the developer.
  /// If the `FLUTTER_BUILD_MODE` and `CONFIGURATION` do not contain either
  /// debug, profile, or release, prints an error and exits the build.
  String parseFlutterBuildMode() {
    // Use FLUTTER_BUILD_MODE if it's set, otherwise use the Xcode build configuration name
    // This means that if someone wants to use an Xcode build config other than Debug/Profile/Release,
    // they _must_ set FLUTTER_BUILD_MODE so we know what type of artifact to build.
    final String? buildMode = (environment['FLUTTER_BUILD_MODE'] ?? environment['CONFIGURATION'])
        ?.toLowerCase();

    if (buildMode != null) {
      if (buildMode.contains('release')) {
        return 'release';
      }
      if (buildMode.contains('profile')) {
        return 'profile';
      }
      if (buildMode.contains('debug')) {
        return 'debug';
      }
    }
    echoError('========================================================================');
    echoError('ERROR: Unknown FLUTTER_BUILD_MODE: $buildMode.');
    echoError("Valid values are 'Debug', 'Profile', or 'Release' (case insensitive).");
    echoError('This is controlled by the FLUTTER_BUILD_MODE environment variable.');
    echoError('If that is not set, the CONFIGURATION environment variable is used.');
    echoError('');
    echoError('You can fix this by either adding an appropriately named build');
    echoError('configuration, or adding an appropriate value for FLUTTER_BUILD_MODE to the');
    echoError(
      '.xcconfig file for the current build configuration (${environment['CONFIGURATION']}).',
    );
    echoError('========================================================================');
    exitApp(-1);
  }

  /// Copies all files from [source] to [destination].
  ///
  /// Does not copy `.DS_Store`.
  ///
  /// Deletes extraneous files from [destination].
  void runRsync(String source, String destination, {List<String> extraArgs = const <String>[]}) {
    runSync('rsync', <String>[
      '-8', // Avoid mangling filenames with encodings that do not match the current locale.
      '-av',
      '--delete',
      '--filter',
      '- .DS_Store',
      ...extraArgs,
      source,
      destination,
    ]);
  }

  /// Embeds the App.framework, Flutter/FlutterMacOS.framework, and any native
  /// asset frameworks into the app.
  ///
  /// On macOS, also codesigns the framework binaries. Codesigning occurs here rather
  /// than during the Run Script `build` phase because the `EXPANDED_CODE_SIGN_IDENTITY`
  /// is not passed in the build settings during the `build` phase for macOS.
  ///
  /// On iOS, also injects local network permissions into the app's Info.plist.
  void embedFlutterFrameworks(TargetPlatform platform) {
    // Embed App.framework from Flutter into the app (after creating the Frameworks directory
    // if it doesn't already exist).
    final xcodeFrameworksDir =
        '${environment['TARGET_BUILD_DIR']}/${environment['FRAMEWORKS_FOLDER_PATH']}';
    runSync('mkdir', <String>['-p', '--', xcodeFrameworksDir]);
    runRsync('${environment['BUILT_PRODUCTS_DIR']}/App.framework', xcodeFrameworksDir);

    final String? expandedCodeSignIdentity = environment['EXPANDED_CODE_SIGN_IDENTITY'];

    final bool codesign =
        platform == TargetPlatform.macos &&
        expandedCodeSignIdentity != null &&
        expandedCodeSignIdentity.isNotEmpty &&
        environment['CODE_SIGNING_REQUIRED'] != 'NO';

    // Embed the actual Flutter.framework that the Flutter app expects to run against,
    // which could be a local build or an arch/type specific build.
    switch (platform) {
      case TargetPlatform.ios:
        runRsync('${environment['BUILT_PRODUCTS_DIR']}/Flutter.framework', '$xcodeFrameworksDir/');
      case TargetPlatform.macos:
        runRsync(
          extraArgs: <String>['--filter', '- Headers', '--filter', '- Modules'],
          '${environment['BUILT_PRODUCTS_DIR']}/FlutterMacOS.framework',
          '$xcodeFrameworksDir/',
        );

        if (codesign) {
          _codesignFramework(expandedCodeSignIdentity, '$xcodeFrameworksDir/App.framework/App');
          _codesignFramework(
            expandedCodeSignIdentity,
            '$xcodeFrameworksDir/FlutterMacOS.framework/FlutterMacOS',
          );
        }
    }

    _embedNativeAssets(
      platform,
      xcodeFrameworksDir: xcodeFrameworksDir,
      codesign: codesign,
      expandedCodeSignIdentity: expandedCodeSignIdentity,
    );

    if (platform == TargetPlatform.ios) {
      addVmServiceBonjourService();
    }
  }

  void _embedNativeAssets(
    TargetPlatform platform, {
    required String xcodeFrameworksDir,
    required bool codesign,
    String? expandedCodeSignIdentity,
  }) {
    // Copy the native assets.
    final String sourceRoot = environment['SOURCE_ROOT'] ?? '';
    var projectPath = '$sourceRoot/..';
    if (environment['FLUTTER_APPLICATION_PATH'] != null) {
      projectPath = environment['FLUTTER_APPLICATION_PATH']!;
    }
    final String flutterBuildDir = environment['FLUTTER_BUILD_DIR']!;
    final nativeAssetsPath = '$projectPath/$flutterBuildDir/native_assets/${platform.name}/';
    final bool verbose = (environment['VERBOSE_SCRIPT_LOGGING'] ?? '').isNotEmpty;
    final Directory nativeAssetsDir = directoryFromPath(nativeAssetsPath);
    if (!nativeAssetsDir.existsSync()) {
      if (verbose) {
        print("♦ No native assets to bundle. $nativeAssetsPath doesn't exist.");
      }
      return;
    }

    if (verbose) {
      print('♦ Copying native assets from $nativeAssetsPath.');
    }
    for (final FileSystemEntity entity in nativeAssetsDir.listSync()) {
      if (entity is Directory) {
        final String? frameworkName = parseFrameworkNameFromDirectory(entity);
        if (frameworkName != null) {
          runRsync(
            extraArgs: <String>[
              '--filter',
              '- native_assets.yaml',
              '--filter',
              '- native_assets.json',
            ],
            entity.path,
            xcodeFrameworksDir,
          );
          if (codesign && expandedCodeSignIdentity != null) {
            _codesignFramework(
              expandedCodeSignIdentity,
              '$xcodeFrameworksDir/$frameworkName.framework/$frameworkName',
            );
          }
        }
      }
    }
  }

  void _codesignFramework(String expandedCodeSignIdentity, String frameworkPath) {
    runSync('codesign', <String>[
      '--force',
      '--verbose',
      '--sign',
      expandedCodeSignIdentity,
      '--',
      frameworkPath,
    ]);
  }

  /// Parse the [dir]'s path to get the framework name. For example,
  /// `/path/to/framework_name.framework/` would parse to `framework_name`.
  ///
  /// Returns null if [dir] is not a `.framework`.
  static String? parseFrameworkNameFromDirectory(Directory dir) {
    final List<String> pathSegments = dir.uri.pathSegments;
    if (pathSegments.isEmpty) {
      return null;
    }
    final String basename;
    if (pathSegments.last.isEmpty && pathSegments.length > 1) {
      basename = pathSegments[pathSegments.length - 2];
    } else {
      basename = pathSegments.last;
    }
    final int extensionIndex = basename.indexOf('.framework');
    if (extensionIndex == -1) {
      return null;
    }
    return basename.substring(0, extensionIndex);
  }

  /// Add the vmService publisher Bonjour service to the produced app bundle Info.plist.
  void addVmServiceBonjourService() {
    // Skip adding Bonjour service settings when DISABLE_PORT_PUBLICATION is YES.
    // These settings are not needed if port publication is disabled.
    if (environment['DISABLE_PORT_PUBLICATION'] == 'YES') {
      return;
    }

    final String buildMode = parseFlutterBuildMode();

    // Debug and profile only.
    if (buildMode == 'release') {
      return;
    }

    final builtProductsPlist =
        '${environment['BUILT_PRODUCTS_DIR'] ?? ''}/${environment['INFOPLIST_PATH'] ?? ''}';

    if (!existsFile(builtProductsPlist)) {
      // Very occasionally Xcode hasn't created an Info.plist when this runs.
      // The file will be present on re-run.
      echo(
        '${environment['INFOPLIST_PATH'] ?? ''} does not exist. Skipping '
        '_dartVmService._tcp NSBonjourServices insertion. Try re-building to '
        'enable "flutter attach".',
      );
      return;
    }

    final bool verbose = (environment['VERBOSE_SCRIPT_LOGGING'] ?? '').isNotEmpty;

    // If there are already NSBonjourServices specified by the app (uncommon),
    // insert the vmService service name to the existing list.
    ProcessResult result = runSync(
      'plutil',
      <String>['-extract', 'NSBonjourServices', 'xml1', '-o', '-', builtProductsPlist],
      verbose: verbose,
      allowFail: true,
      skipErrorLog: true,
    );
    if (result.exitCode == 0) {
      runSync('plutil', <String>[
        '-insert',
        'NSBonjourServices.0',
        '-string',
        '_dartVmService._tcp',
        builtProductsPlist,
      ]);
    } else {
      // Otherwise, add the NSBonjourServices key and vmService service name.
      runSync('plutil', <String>[
        '-insert',
        'NSBonjourServices',
        '-json',
        '["_dartVmService._tcp"]',
        builtProductsPlist,
      ]);
      //fi
    }

    // Don't override the local network description the Flutter app developer
    // specified (uncommon). This text will appear below the "Your app would
    // like to find and connect to devices on your local network" permissions
    // popup.
    result = runSync(
      'plutil',
      <String>['-extract', 'NSLocalNetworkUsageDescription', 'xml1', '-o', '-', builtProductsPlist],
      verbose: verbose,
      allowFail: true,
      skipErrorLog: true,
    );
    if (result.exitCode != 0) {
      runSync('plutil', <String>[
        '-insert',
        'NSLocalNetworkUsageDescription',
        '-string',
        'Allow Flutter tools on your computer to connect and debug your application. This prompt will not appear on release builds.',
        builtProductsPlist,
      ]);
    }
  }

  /// Calls `flutter assemble [buildMode]_unpack_[platform]` (e.g. `debug_unpack_ios`, `debug_unpack_macos`)
  void prepare(TargetPlatform platform) {
    // The "prepare" command runs in a pre-action script, which also runs when
    // using the Xcode/xcodebuild clean command. Skip if cleaning.
    if (environment['ACTION'] == 'clean') {
      return;
    }
    final bool verbose = (environment['VERBOSE_SCRIPT_LOGGING'] ?? '').isNotEmpty;
    final String sourceRoot = environment['SOURCE_ROOT'] ?? '';
    final String projectPath = environment['FLUTTER_APPLICATION_PATH'] ?? '$sourceRoot/..';

    final String buildMode = parseFlutterBuildMode();

    final List<String> flutterArgs = _generateFlutterArgsForAssemble(
      command: 'prepare',
      buildMode: buildMode,
      sourceRoot: sourceRoot,
      platform: platform,
      verbose: verbose,
    );

    // The "prepare" command only targets the UnpackIOS/UnpackMacOS target, which copies the
    // Flutter framework to the BUILT_PRODUCTS_DIR.
    flutterArgs.add('${buildMode}_unpack_${platform.name}');

    final ProcessResult result = runSync(
      '${environmentEnsure('FLUTTER_ROOT')}/bin/flutter',
      flutterArgs,
      verbose: verbose,
      allowFail: true,
      workingDirectory: projectPath, // equivalent of RunCommand pushd "${project_path}"
    );

    if (result.exitCode != 0) {
      echoError('Failed to copy Flutter framework.');
      exitApp(-1);
    }
  }

  /// Calls `flutter assemble [buildMode]_[platform]_bundle_flutter_assets`
  /// (e.g. `debug_ios_bundle_flutter_assets`, `debug_macos_bundle_flutter_assets`)
  void buildApp(TargetPlatform platform) {
    final bool verbose = (environment['VERBOSE_SCRIPT_LOGGING'] ?? '').isNotEmpty;
    final String sourceRoot = environment['SOURCE_ROOT'] ?? '';
    final String projectPath = environment['FLUTTER_APPLICATION_PATH'] ?? '$sourceRoot/..';

    final String buildMode = parseFlutterBuildMode();

    _validateBuildMode(platform, buildMode);

    final List<String> flutterArgs = _generateFlutterArgsForAssemble(
      command: 'build',
      buildMode: buildMode,
      sourceRoot: sourceRoot,
      platform: platform,
      verbose: verbose,
    );

    flutterArgs.add('${buildMode}_${platform.name}_bundle_flutter_assets');
    final ProcessResult result = runSync(
      '${environmentEnsure('FLUTTER_ROOT')}/bin/flutter',
      flutterArgs,
      verbose: verbose,
      allowFail: true,
      workingDirectory: projectPath, // equivalent of RunCommand pushd "${project_path}"
    );

    if (result.exitCode != 0) {
      echoError('Failed to package $projectPath.');
      exitApp(-1);
    }

    streamOutput('done');
    streamOutput(' └─Compiling, linking and signing...');

    echo('Project $projectPath built and packaged successfully.');
  }

  /// Validate that the build mode targeted matches the build mode set by the
  /// Flutter CLI.
  /// If it doesn't match, print a warning unless the Xcode action is `install`,
  /// which means the app is being archived for distribution. In that case, print
  /// an error and fail the build.
  ///
  /// The targeted build mode might not match the one set by Flutter CLI when it
  /// is changed and ran directly through Xcode.
  ///
  /// Flutter may change settings or files depending on the build mode. For
  /// example, dev dependencies are excluded from release builds and requires
  /// the Flutter CLI to update certain files.
  void _validateBuildMode(TargetPlatform platform, String currentBuildMode) {
    final String? buildModeCLILastUsed = environment['FLUTTER_CLI_BUILD_MODE'];

    // Also fail the build if ACTION=install, which indicates the app is being
    // built for distribution.
    final String? action = environment['ACTION'];
    final fatal = action == 'install';

    if (buildModeCLILastUsed == null) {
      final message =
          'Your Flutter build settings are outdated. Please run '
          '"flutter build ${platform.name} --config-only --$currentBuildMode" in your Flutter '
          'project and try again.\n';
      if (fatal) {
        echoXcodeError(message);
        exitApp(-1);
      } else {
        echoXcodeWarning(message);
        return;
      }
    }
    if (currentBuildMode != buildModeCLILastUsed) {
      final message =
          'Your Flutter project is currently configured for $buildModeCLILastUsed mode. '
          'Please run `flutter build ${platform.name} --config-only --$currentBuildMode` '
          'in your Flutter project to update your settings.\n';
      if (fatal) {
        echoXcodeError(message);
        exitApp(-1);
      } else {
        echoXcodeWarning(message);
      }
    }
  }

  List<String> _generateFlutterArgsForAssemble({
    required String command,
    required String buildMode,
    required String sourceRoot,
    required TargetPlatform platform,
    required bool verbose,
  }) {
    var targetPath = 'lib/main.dart';
    if (environment['FLUTTER_TARGET'] != null) {
      targetPath = environment['FLUTTER_TARGET']!;
    }

    // Warn the user if not archiving (ACTION=install) in release mode.
    final String? action = environment['ACTION'];
    if (action == 'install' && buildMode != 'release') {
      echoXcodeWarning(
        'Flutter archive not built in Release mode. Ensure '
        'FLUTTER_BUILD_MODE is set to release or run "flutter build ios '
        '--release", then re-run Archive from Xcode.',
      );
    }

    final flutterArgs = <String>[];

    if (verbose) {
      flutterArgs.add('--verbose');
    }

    if (environment['FLUTTER_ENGINE'] != null && environment['FLUTTER_ENGINE']!.isNotEmpty) {
      flutterArgs.add('--local-engine-src-path=${environment['FLUTTER_ENGINE']}');
    }

    if (environment['LOCAL_ENGINE'] != null && environment['LOCAL_ENGINE']!.isNotEmpty) {
      flutterArgs.add('--local-engine=${environment['LOCAL_ENGINE']}');
    }

    if (environment['LOCAL_ENGINE_HOST'] != null && environment['LOCAL_ENGINE_HOST']!.isNotEmpty) {
      flutterArgs.add('--local-engine-host=${environment['LOCAL_ENGINE_HOST']}');
    }

    // The "prepare" command runs in a pre-action script, which doesn't always
    // filter the "ARCHS" build setting. Attempt to filter the architecture
    // to improve caching. If this filter is incorrect, it will later be
    // corrected by the "build" command.
    String archs = environment['ARCHS'] ?? '';
    if (command == 'prepare' && archs.contains(' ')) {
      // If "ONLY_ACTIVE_ARCH" is "YES", the product includes only code for the
      // native architecture ("NATIVE_ARCH").
      final String? nativeArch = environment['NATIVE_ARCH'];
      if (environment['ONLY_ACTIVE_ARCH'] == 'YES' && nativeArch != null) {
        if (nativeArch.contains('arm64') && archs.contains('arm64')) {
          archs = 'arm64';
        } else if (nativeArch.contains('x86_64') && archs.contains('x86_64')) {
          archs = 'x86_64';
        }
      }
    }

    final String targetPlatform;
    final String platformArches;
    switch (platform) {
      case TargetPlatform.ios:
        targetPlatform = '-dTargetPlatform=ios';
        platformArches = '-dIosArchs=$archs';
      case TargetPlatform.macos:
        targetPlatform = '-dTargetPlatform=darwin';
        platformArches = '-dDarwinArchs=$archs';
    }

    flutterArgs.addAll(<String>[
      'assemble',
      '--no-version-check',
      '--output=${environment['BUILT_PRODUCTS_DIR'] ?? ''}/',
      targetPlatform,
      '-dTargetFile=$targetPath',
      '-dBuildMode=$buildMode',
      // FLAVOR is set by the Flutter CLI in the Flutter/Generated.xcconfig file
      // when the --flavor flag is used, so it may not always be present.
      if (environment['FLAVOR'] != null) '-dFlavor=${environment['FLAVOR']}',
      '-dConfiguration=${environment['CONFIGURATION']}',
      platformArches,
      '-dSdkRoot=${environment['SDKROOT'] ?? ''}',
      '-dSplitDebugInfo=${environment['SPLIT_DEBUG_INFO'] ?? ''}',
      '-dTreeShakeIcons=${environment['TREE_SHAKE_ICONS'] ?? ''}',
      '-dTrackWidgetCreation=${environment['TRACK_WIDGET_CREATION'] ?? ''}',
      '-dDartObfuscation=${environment['DART_OBFUSCATION'] ?? ''}',
      '-dAction=${environment['ACTION'] ?? ''}',
      '-dFrontendServerStarterPath=${environment['FRONTEND_SERVER_STARTER_PATH'] ?? ''}',
      '--ExtraGenSnapshotOptions=${environment['EXTRA_GEN_SNAPSHOT_OPTIONS'] ?? ''}',
      '--DartDefines=${environment['DART_DEFINES'] ?? ''}',
      '--ExtraFrontEndOptions=${environment['EXTRA_FRONT_END_OPTIONS'] ?? ''}',
      '-dSrcRoot=${environment['SRCROOT'] ?? ''}',
    ]);

    if (platform == TargetPlatform.ios) {
      flutterArgs.add('-dTargetDeviceOSVersion=${environment['TARGET_DEVICE_OS_VERSION'] ?? ''}');
      final String? expandedCodeSignIdentity = environment['EXPANDED_CODE_SIGN_IDENTITY'];
      if (expandedCodeSignIdentity != null &&
          expandedCodeSignIdentity.isNotEmpty &&
          environment['CODE_SIGNING_REQUIRED'] != 'NO') {
        flutterArgs.add('-dCodesignIdentity=$expandedCodeSignIdentity');
      }
    }
    if (platform == TargetPlatform.macos && command == 'build') {
      final ephemeralDirectory = '$sourceRoot/Flutter/ephemeral';
      final buildInputsPath = '$ephemeralDirectory/FlutterInputs.xcfilelist';
      final buildOutputsPath = '$ephemeralDirectory/FlutterOutputs.xcfilelist';
      flutterArgs.addAll(<String>[
        '--build-inputs=$buildInputsPath',
        '--build-outputs=$buildOutputsPath',
      ]);
    }

    if (command == 'prepare') {
      // Use the PreBuildAction define flag to force the tool to use a different
      // filecache file for the "prepare" command. This will make the environment
      // buildPrefix for the "prepare" command unique from the "build" command.
      // This will improve caching since the "build" command has more target dependencies.
      flutterArgs.add('-dPreBuildAction=PrepareFramework');
    }

    if (environment['PERFORMANCE_MEASUREMENT_FILE'] != null &&
        environment['PERFORMANCE_MEASUREMENT_FILE']!.isNotEmpty) {
      flutterArgs.add(
        '--performance-measurement-file=${environment['PERFORMANCE_MEASUREMENT_FILE']}',
      );
    }

    if (environment['CODE_SIZE_DIRECTORY'] != null &&
        environment['CODE_SIZE_DIRECTORY']!.isNotEmpty) {
      flutterArgs.add('-dCodeSizeDirectory=${environment['CODE_SIZE_DIRECTORY']}');
    }

    return flutterArgs;
  }
}

enum TargetPlatform {
  ios('ios'),
  macos('macos');

  const TargetPlatform(this.name);
  final String name;
}
