// 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:convert';
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':
        unpackFor(platform, 'prepare');
      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);

  File fileFromPath(String path) => File(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]);

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

    _embedAppFramework(xcodeFrameworksDir, codesign ? expandedCodeSignIdentity : null);

    var shouldEmbedFlutterFramework = true;
    if (_usingFlutterFrameworkSwiftPackage()) {
      final bool isFrameworkCorrect = _validateFlutterFramework(
        buildMode: parseFlutterBuildMode(),
        platform: platform,
        builtProductsDir: environment['BUILT_PRODUCTS_DIR'],
        targetBuildDir: xcodeFrameworksDir,
      );
      if (isFrameworkCorrect) {
        // If the engine is correct, skip embedding.
        shouldEmbedFlutterFramework = false;
      } else {
        // If the engine is wrong in either BUILT_PRODUCTS_DIR or TARGET_BUILD_DIR, call unpack
        // again so the correct framework is copied into BUILT_PRODUCTS_DIR to then be embedded
        // into TARGET_BUILD_DIR below.
        unpackFor(platform, 'embed');
      }
    }

    if (shouldEmbedFlutterFramework) {
      // 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/FlutterMacOS.framework/FlutterMacOS',
            );
          }
      }
    }

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

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

  void _embedAppFramework(String xcodeFrameworksDir, String? expandedCodeSignIdentity) {
    runRsync('${environment['BUILT_PRODUCTS_DIR']}/App.framework', xcodeFrameworksDir);
    if (expandedCodeSignIdentity != null) {
      _codesignFramework(expandedCodeSignIdentity, '$xcodeFrameworksDir/App.framework/App');
    }
  }

  /// Returns `true` if a directory exists at `FLUTTER_FRAMEWORK_SWIFT_PACKAGE_PATH`.
  bool _usingFlutterFrameworkSwiftPackage() {
    final String? swiftPackagePath = environment['FLUTTER_FRAMEWORK_SWIFT_PACKAGE_PATH'];
    if (swiftPackagePath == null) {
      return false;
    }
    final swiftPackage = Directory(swiftPackagePath);
    return swiftPackage.existsSync();
  }

  /// Returns `true` if the Flutter/FlutterMacOS framework Info.plist in [builtProductsDir] and
  /// [targetBuildDir] matches the framework Info.plist from the engine cache for the
  /// corresponding [platform] and [buildMode].
  ///
  /// The Info.plist contains the build mode and engine version.
  ///
  /// This validation will always fail when using a local engine since the engine version will not match.
  bool _validateFlutterFramework({
    required String buildMode,
    required TargetPlatform platform,
    required String? builtProductsDir,
    required String? targetBuildDir,
  }) {
    if (builtProductsDir == null) {
      echo('Unable to locate $builtProductsDir; falling back to direct embedding.');
      return false;
    }
    if (targetBuildDir == null) {
      echo('Unable to locate $targetBuildDir; falling back to direct embedding.');
      return false;
    }
    try {
      final infoPlistFromBuild = File('$builtProductsDir/${platform.infoPlistPath}');
      if (!infoPlistFromBuild.existsSync()) {
        echo('Unable to locate $infoPlistFromBuild; falling back to direct embedding.');
        return false;
      }
      final infoPlistFromEmbedded = File('$targetBuildDir/${platform.infoPlistPath}');
      if (!infoPlistFromEmbedded.existsSync()) {
        echo('Unable to locate $infoPlistFromEmbedded; falling back to direct embedding.');
        return false;
      }

      final File? infoPlistFromEngineCache = _infoPlistFromEngineCache(buildMode, platform);
      if (infoPlistFromEngineCache == null || !infoPlistFromEngineCache.existsSync()) {
        echo('Unable to locate $infoPlistFromEngineCache; falling back to direct embedding.');
        return false;
      }
      final String expectedInfoPlist = infoPlistFromEngineCache.readAsStringSync();
      if (infoPlistFromBuild.readAsStringSync() != expectedInfoPlist) {
        echo(
          'Initially processed Flutter framework did not match expectations; falling back to direct embedding.',
        );
        return false;
      }
      if (infoPlistFromEmbedded.readAsStringSync() != expectedInfoPlist) {
        echo(
          'Initially embedded Flutter framework did not match expectations; falling back to direct embedding.',
        );
        return false;
      }
      return infoPlistFromBuild.readAsStringSync() == expectedInfoPlist &&
          infoPlistFromEmbedded.readAsStringSync() == expectedInfoPlist;
    } on Exception catch (e) {
      // Use `echo` instead of `echoError` so it does not cause the build to fail.
      echo('$e\n');
      echo(
        'An error occured while validating the Flutter framework; falling back to direct embedding.\n',
      );
    }
    return false;
  }

  /// Find the Info.plist of the Flutter/FlutterMacOS framework for the corresponding [buildMode]
  /// and [platform].
  File? _infoPlistFromEngineCache(String buildMode, TargetPlatform platform) {
    final String artifactMode = buildMode == 'debug'
        ? platform.artifactName
        : '${platform.artifactName}-$buildMode';
    final xcframework = Directory(
      '${environment['FLUTTER_ROOT'] ?? ''}/bin/cache/artifacts/engine/$artifactMode/${platform.frameworkName}.xcframework',
    );
    switch (platform) {
      case TargetPlatform.ios:
        final String? sdkRoot = environment['SDKROOT']?.toLowerCase();
        if (sdkRoot == null || !sdkRoot.contains('iphone')) {
          return null;
        }
        final bool simulatorSDK = sdkRoot.contains('simulator');
        for (final FileSystemEntity entity in xcframework.listSync()) {
          final String platformBaseName = Uri.parse(entity.path).pathSegments.last;
          if (entity is Directory && platformBaseName.startsWith('ios-')) {
            final bool isSimulatorDirectory = platformBaseName.endsWith('-simulator');
            if (simulatorSDK == isSimulatorDirectory) {
              return File('${entity.path}/${platform.infoPlistPath}');
            }
          }
        }
      case TargetPlatform.macos:
        for (final FileSystemEntity entity in xcframework.listSync()) {
          final String platformBaseName = Uri.parse(entity.path).pathSegments.last;
          if (entity is Directory && platformBaseName.startsWith('macos-')) {
            return File('${entity.path}/${platform.infoPlistPath}');
          }
        }
    }
    return null;
  }

  void _embedNativeAssets(
    TargetPlatform platform, {
    required String xcodeFrameworksDir,
    required bool codesign,
    String? expandedCodeSignIdentity,
  }) {
    // Copy native assets referenced in the native_assets.json file for the
    // current build.
    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 Set<String> referencedFrameworks = {};
    final appResourcesDir = platform == TargetPlatform.macos ? 'Resources/' : '';
    final File nativeAssetsJson = fileFromPath(
      '$xcodeFrameworksDir/App.framework/${appResourcesDir}flutter_assets/NativeAssetsManifest.json',
    );
    if (!nativeAssetsJson.existsSync()) {
      if (verbose) {
        print("♦ No native assets to bundle. ${nativeAssetsJson.path} doesn't exist.");
      }
      return;
    }
    // NativeAssetsManifest.json looks like this: {
    //   "format-version":[1,0,0],
    //   "native-assets":{
    //     "ios_arm64":{
    //       "package:sqlite3/src/ffi/libsqlite3.g.dart":[
    //         "absolute",
    //         "sqlite3arm64ios.framework/sqlite3arm64ios"
    //       ]
    //     }
    //   }
    // }
    //
    // Note that this format is also parsed and expected in
    // engine/src/flutter/assets/native_assets.cc
    try {
      final nativeAssetsSpec = json.decode(nativeAssetsJson.readAsStringSync()) as Map;
      for (final Object? perPlatform
          in (nativeAssetsSpec['native-assets'] as Map<String, Object?>).values) {
        for (final Object? asset in (perPlatform! as Map<String, Object?>).values) {
          if (asset case ['absolute', final String frameworkPath]) {
            // frameworkPath is usually something like sqlite3arm64ios.framework/sqlite3arm64ios
            final [String directory, String name] = frameworkPath.split('/');
            if (directory != '$name.framework') {
              throw Exception(
                'Unexpected framework path: $frameworkPath. Should be $name.framework/$name',
              );
            }

            referencedFrameworks.add(name);
          }
        }
      }
    } on Object catch (e, stackTrace) {
      echo(e.toString());
      echo(stackTrace.toString());
      echoXcodeError('Failed to embed native assets: $e');
      exitApp(-1);
    }

    if (verbose) {
      print('♦ Copying native assets ${referencedFrameworks.join(', ')} from $nativeAssetsPath.');
    }

    for (final framework in referencedFrameworks) {
      final Directory frameworkDirectory = directoryFromPath(
        '$nativeAssetsPath$framework.framework',
      );
      if (!frameworkDirectory.existsSync()) {
        throw Exception(
          'The native assets specification at ${nativeAssetsJson.path} references $framework, '
          'which was not found in $nativeAssetsPath.',
        );
      }

      runRsync(frameworkDirectory.path, xcodeFrameworksDir);
      if (codesign && expandedCodeSignIdentity != null) {
        _codesignFramework(
          expandedCodeSignIdentity,
          '$xcodeFrameworksDir/$framework.framework/$framework',
        );
      }

      final Directory dsymDirectory = directoryFromPath(
        '$nativeAssetsPath$framework.framework.dSYM',
      );
      if (dsymDirectory.existsSync()) {
        runRsync(dsymDirectory.path, '${environment['BUILT_PRODUCTS_DIR']}/');
      }
    }
  }

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

  /// 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 unpackFor(TargetPlatform platform, String command) {
    // 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: command,
      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();

    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.');
  }

  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'] ?? ''}',
      '-dXcodeBuildScript=$command',
    ]);

    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 (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(artifactName: 'ios', frameworkName: 'Flutter', infoPlistPath: 'Flutter.framework/Info.plist'),
  macos(
    artifactName: 'darwin-x64',
    frameworkName: 'FlutterMacOS',
    infoPlistPath: 'FlutterMacOS.framework/Resources/Info.plist',
  );

  const TargetPlatform({
    required this.artifactName,
    required this.frameworkName,
    required this.infoPlistPath,
  });

  final String artifactName;
  final String frameworkName;
  final String infoPlistPath;
}
