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

  void run() {
    if (arguments.isEmpty) {
      // Named entry points were introduced in Flutter v0.0.7.
      stderr.write(
          'error: Your Xcode project is incompatible with this version of Flutter. '
          'Run "rm -rf ios/Runner.xcodeproj" and "flutter create ." to regenerate.\n');
      exit(-1);
    }

    final String subCommand = arguments.first;
    switch (subCommand) {
      case 'build':
        buildApp();
        break;
      case 'thin':
        // No-op, thinning is handled during the bundle asset assemble build target.
        break;
      case 'embed':
        embedFlutterFrameworks();
        break;
      case 'embed_and_thin':
        // Thinning is handled during the bundle asset assemble build target, so just embed.
        embedFlutterFrameworks();
        break;
      case 'test_observatory_bonjour_service':
        // Exposed for integration testing only.
        addObservatoryBonjourService();
    }
  }

  bool existsDir(String path) {
    final Directory dir = Directory(path);
    return dir.existsSync();
  }

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

  /// Run given command in a synchronous subprocess.
  ///
  /// Will throw [Exception] if the exit code is not 0.
  ProcessResult runSync(
    String bin,
    List<String> args, {
    bool verbose = false,
    bool allowFail = false,
    String? workingDirectory,
  }) {
    if (verbose) {
      print('♦ $bin ${args.join(' ')}');
    }
    final ProcessResult result = Process.runSync(
      bin,
      args,
      workingDirectory: workingDirectory,
    );
    if (verbose) {
      print((result.stdout as String).trim());
    }
    if ((result.stderr as String).isNotEmpty) {
      echoError((result.stderr as String).trim());
    }
    if (!allowFail && result.exitCode != 0) {
      stderr.write('${result.stderr}\n');
      throw Exception(
        'Command "$bin ${args.join(' ')}" exited with code ${result.exitCode}',
      );
    }
    return result;
  }

  /// Log message to stderr.
  void echoError(String message) {
    stderr.writeln(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');
  }

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

  // Adds the App.framework as an embedded binary and the flutter_assets as
  // resources.
  void embedFlutterFrameworks() {
    // Embed App.framework from Flutter into the app (after creating the Frameworks directory
    // if it doesn't already exist).
    final String xcodeFrameworksDir = '${environment['TARGET_BUILD_DIR']}/${environment['FRAMEWORKS_FOLDER_PATH']}';
    runSync(
      'mkdir',
      <String>[
        '-p',
        '--',
        xcodeFrameworksDir,
      ]
    );
    runSync(
      'rsync',
      <String>[
        '-8', // Avoid mangling filenames with encodings that do not match the current locale.
        '-av',
        '--delete',
        '--filter',
        '- .DS_Store',
        '${environment['BUILT_PRODUCTS_DIR']}/App.framework',
        xcodeFrameworksDir,
      ],
    );

    // 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.
    runSync(
      'rsync',
      <String>[
        '-av',
        '--delete',
        '--filter',
        '- .DS_Store',
        '${environment['BUILT_PRODUCTS_DIR']}/Flutter.framework',
        '$xcodeFrameworksDir/',
      ],
    );

    addObservatoryBonjourService();
  }

  // Add the observatory publisher Bonjour service to the produced app bundle Info.plist.
  void addObservatoryBonjourService() {
    final String buildMode = parseFlutterBuildMode();

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

    final String 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 '
        '_dartobservatory._tcp NSBonjourServices insertion. Try re-building to '
        'enable "flutter attach".');
      return;
    }

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

  void buildApp() {
    final bool verbose = environment['VERBOSE_SCRIPT_LOGGING'] != null && environment['VERBOSE_SCRIPT_LOGGING'] != '';
    final String sourceRoot = environment['SOURCE_ROOT'] ?? '';
    String projectPath = '$sourceRoot/..';
    if (environment['FLUTTER_APPLICATION_PATH'] != null) {
      projectPath = environment['FLUTTER_APPLICATION_PATH']!;
    }

    String targetPath = 'lib/main.dart';
    if (environment['FLUTTER_TARGET'] != null) {
      targetPath = environment['FLUTTER_TARGET']!;
    }

    String derivedDir = '$sourceRoot/Flutter}';
    if (existsDir('$projectPath/.ios')) {
      derivedDir = '$projectPath/.ios/Flutter';
    }

    // 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 = parseFlutterBuildMode();
    String artifactVariant = 'unknown';
    switch (buildMode) {
      case 'release':
        artifactVariant = 'ios-release';
        break;
      case 'profile':
        artifactVariant = 'ios-profile';
        break;
      case 'debug':
        artifactVariant = 'ios';
        break;
    }

    // Warn the user if not archiving (ACTION=install) in release mode.
    final String? action = environment['ACTION'];
    if (action == 'install' && buildMode != 'release') {
      echo(
        'warning: 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 String frameworkPath = '${environmentEnsure('FLUTTER_ROOT')}/bin/cache/artifacts/engine/$artifactVariant';

    String flutterFramework = '$frameworkPath/Flutter.xcframework';

    final String? localEngine = environment['LOCAL_ENGINE'];
    if (localEngine != null) {
      if (!localEngine.toLowerCase().contains(buildMode)) {
        echoError('========================================================================');
        echoError("ERROR: Requested build with Flutter local engine at '$localEngine'");
        echoError("This engine is not compatible with FLUTTER_BUILD_MODE: '$buildMode'.");
        echoError('You can fix this by updating the LOCAL_ENGINE environment variable, or');
        echoError('by running:');
        echoError('  flutter build ios --local-engine=ios_$buildMode');
        echoError('or');
        echoError('  flutter build ios --local-engine=ios_${buildMode}_unopt');
        echoError('========================================================================');
        exitApp(-1);
      }
      flutterFramework = '${environmentEnsure('FLUTTER_ENGINE')}/out/$localEngine/Flutter.xcframework';
    }
    String bitcodeFlag = '';
    if (environment['ENABLE_BITCODE'] == 'YES' && environment['ACTION'] == 'install') {
      bitcodeFlag = 'true';
    }

    // TODO(jmagman): use assemble copied engine in add-to-app.
    if (existsDir('$projectPath/.ios')) {
      runSync(
        'rsync',
        <String>[
          '-av',
          '--delete',
          '--filter',
          '- .DS_Store',
          flutterFramework,
          '$derivedDir/engine',
        ],
        verbose: verbose,
      );
    }

    final List<String> 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']}');
    }

    flutterArgs.addAll(<String>[
      'assemble',
      '--no-version-check',
      '--output=${environment['BUILT_PRODUCTS_DIR'] ?? ''}/',
      '-dTargetPlatform=ios',
      '-dTargetFile=$targetPath',
      '-dBuildMode=$buildMode',
      '-dIosArchs=${environment['ARCHS'] ?? ''}',
      '-dSdkRoot=${environment['SDKROOT'] ?? ''}',
      '-dSplitDebugInfo=${environment['SPLIT_DEBUG_INFO'] ?? ''}',
      '-dTreeShakeIcons=${environment['TREE_SHAKE_ICONS'] ?? ''}',
      '-dTrackWidgetCreation=${environment['TRACK_WIDGET_CREATION'] ?? ''}',
      '-dDartObfuscation=${environment['DART_OBFUSCATION'] ?? ''}',
      '-dEnableBitcode=$bitcodeFlag',
      '--ExtraGenSnapshotOptions=${environment['EXTRA_GEN_SNAPSHOT_OPTIONS'] ?? ''}',
      '--DartDefines=${environment['DART_DEFINES'] ?? ''}',
      '--ExtraFrontEndOptions=${environment['EXTRA_FRONT_END_OPTIONS'] ?? ''}',
    ]);

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

    final String? expandedCodeSignIdentity = environment['EXPANDED_CODE_SIGN_IDENTITY'];
    if (expandedCodeSignIdentity != null && expandedCodeSignIdentity.isNotEmpty && environment['CODE_SIGNING_REQUIRED'] != 'NO') {
      flutterArgs.add('-dCodesignIdentity=$expandedCodeSignIdentity');
    }

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

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

    flutterArgs.add('${buildMode}_ios_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.');
  }
}
