// 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 '../../artifacts.dart';
import '../../base/build.dart';
import '../../base/deferred_component.dart';
import '../../base/file_system.dart';
import '../../build_info.dart';
import '../../globals.dart' as globals show xcode;
import '../../project.dart';
import '../build_system.dart';
import '../depfile.dart';
import '../exceptions.dart';
import 'assets.dart';
import 'common.dart';
import 'icon_tree_shaker.dart';
import 'shader_compiler.dart';

/// Prepares the asset bundle in the format expected by flutter.gradle.
///
/// The vm_snapshot_data, isolate_snapshot_data, and kernel_blob.bin are
/// expected to be in the root output directory.
///
/// All assets and manifests are included from flutter_assets/**.
abstract class AndroidAssetBundle extends Target {
  const AndroidAssetBundle();

  @override
  List<Source> get inputs => const <Source>[
    Source.pattern('{BUILD_DIR}/app.dill'),
    ...IconTreeShaker.inputs,
  ];

  @override
  List<Source> get outputs => const <Source>[];

  @override
  List<String> get depfiles => <String>[
    'flutter_assets.d',
  ];

  @override
  Future<void> build(Environment environment) async {
    final String? buildModeEnvironment = environment.defines[kBuildMode];
    if (buildModeEnvironment == null) {
      throw MissingDefineException(kBuildMode, name);
    }
    final BuildMode buildMode = getBuildModeForName(buildModeEnvironment);
    final Directory outputDirectory = environment.outputDir
      .childDirectory('flutter_assets')
      ..createSync(recursive: true);

    // Only copy the prebuilt runtimes and kernel blob in debug mode.
    if (buildMode == BuildMode.debug) {
      final String vmSnapshotData = environment.artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug);
      final String isolateSnapshotData = environment.artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug);
      environment.buildDir.childFile('app.dill')
          .copySync(outputDirectory.childFile('kernel_blob.bin').path);
      environment.fileSystem.file(vmSnapshotData)
          .copySync(outputDirectory.childFile('vm_snapshot_data').path);
      environment.fileSystem.file(isolateSnapshotData)
          .copySync(outputDirectory.childFile('isolate_snapshot_data').path);
    }
    final Depfile assetDepfile = await copyAssets(
      environment,
      outputDirectory,
      targetPlatform: TargetPlatform.android,
      buildMode: buildMode,
      shaderTarget: ShaderTarget.sksl,
    );
    final DepfileService depfileService = DepfileService(
      fileSystem: environment.fileSystem,
      logger: environment.logger,
    );
    depfileService.writeToFile(
      assetDepfile,
      environment.buildDir.childFile('flutter_assets.d'),
    );
  }

  @override
  List<Target> get dependencies => const <Target>[
    KernelSnapshot(),
  ];
}

/// An implementation of [AndroidAssetBundle] that includes dependencies on vm
/// and isolate data.
class DebugAndroidApplication extends AndroidAssetBundle {
  const DebugAndroidApplication();

  @override
  String get name => 'debug_android_application';

  @override
  List<Source> get inputs => <Source>[
    ...super.inputs,
    const Source.artifact(Artifact.vmSnapshotData, mode: BuildMode.debug),
    const Source.artifact(Artifact.isolateSnapshotData, mode: BuildMode.debug),
  ];

  @override
  List<Source> get outputs => <Source>[
    ...super.outputs,
    const Source.pattern('{OUTPUT_DIR}/flutter_assets/vm_snapshot_data'),
    const Source.pattern('{OUTPUT_DIR}/flutter_assets/isolate_snapshot_data'),
    const Source.pattern('{OUTPUT_DIR}/flutter_assets/kernel_blob.bin'),
  ];
}

/// An implementation of [AndroidAssetBundle] that only includes assets.
class AotAndroidAssetBundle extends AndroidAssetBundle {
  const AotAndroidAssetBundle();

  @override
  String get name => 'aot_android_asset_bundle';
}

/// Build a profile android application's Dart artifacts.
class ProfileAndroidApplication extends CopyFlutterAotBundle {
  const ProfileAndroidApplication();

  @override
  String get name => 'profile_android_application';

  @override
  List<Target> get dependencies => const <Target>[
    AotElfProfile(TargetPlatform.android_arm),
    AotAndroidAssetBundle(),
  ];
}

/// Build a release android application's Dart artifacts.
class ReleaseAndroidApplication extends CopyFlutterAotBundle {
  const ReleaseAndroidApplication();

  @override
  String get name => 'release_android_application';

  @override
  List<Target> get dependencies => const <Target>[
    AotElfRelease(TargetPlatform.android_arm),
    AotAndroidAssetBundle(),
  ];
}

/// Generate an ELF binary from a dart kernel file in release mode.
///
/// This rule implementation outputs the generated so to a unique location
/// based on the Android ABI. This allows concurrent invocations of gen_snapshot
/// to run simultaneously.
///
/// The name of an instance of this rule would be 'android_aot_profile_android-x64'
/// and is relied upon by flutter.gradle to match the correct rule.
///
/// It will produce an 'app.so` in the build directory under a folder named with
/// the matching Android ABI.
class AndroidAot extends AotElfBase {
  /// Create an [AndroidAot] implementation for a given [targetPlatform] and [buildMode].
  const AndroidAot(this.targetPlatform, this.buildMode);

  /// The name of the produced Android ABI.
  String get _androidAbiName {
    return getNameForAndroidArch(
      getAndroidArchForName(getNameForTargetPlatform(targetPlatform)));
  }

  @override
  String get name => 'android_aot_${getNameForBuildMode(buildMode)}_'
    '${getNameForTargetPlatform(targetPlatform)}';

  /// The specific Android ABI we are building for.
  final TargetPlatform targetPlatform;

  /// The selected build mode.
  ///
  /// Build mode is restricted to [BuildMode.profile] or [BuildMode.release] for AOT builds.
  final BuildMode buildMode;

  @override
  List<Source> get inputs => <Source>[
    const Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/android.dart'),
    const Source.pattern('{BUILD_DIR}/app.dill'),
    const Source.artifact(Artifact.engineDartBinary),
    const Source.artifact(Artifact.skyEnginePath),
    Source.artifact(Artifact.genSnapshot,
      mode: buildMode,
      platform: targetPlatform,
     ),
  ];

  @override
  List<Source> get outputs => <Source>[
    Source.pattern('{BUILD_DIR}/$_androidAbiName/app.so'),
  ];

  @override
  List<String> get depfiles => <String>[
    'flutter_$name.d',
  ];

  @override
  List<Target> get dependencies => const <Target>[
    KernelSnapshot(),
  ];

  @override
  Future<void> build(Environment environment) async {
    final AOTSnapshotter snapshotter = AOTSnapshotter(
      fileSystem: environment.fileSystem,
      logger: environment.logger,
      xcode: globals.xcode!,
      processManager: environment.processManager,
      artifacts: environment.artifacts,
    );
    final Directory output = environment.buildDir.childDirectory(_androidAbiName);
    final String? buildModeEnvironment = environment.defines[kBuildMode];
    if (buildModeEnvironment == null) {
      throw MissingDefineException(kBuildMode, 'aot_elf');
    }
    if (!output.existsSync()) {
      output.createSync(recursive: true);
    }
    final List<String> extraGenSnapshotOptions = decodeCommaSeparated(environment.defines, kExtraGenSnapshotOptions);
    final List<File> outputs = <File>[]; // outputs for the depfile
    final String manifestPath = '${output.path}${environment.platform.pathSeparator}manifest.json';
    if (environment.defines[kDeferredComponents] == 'true') {
      extraGenSnapshotOptions.add('--loading_unit_manifest=$manifestPath');
      outputs.add(environment.fileSystem.file(manifestPath));
    }
    final BuildMode buildMode = getBuildModeForName(buildModeEnvironment);
    final bool dartObfuscation = environment.defines[kDartObfuscation] == 'true';
    final String? codeSizeDirectory = environment.defines[kCodeSizeDirectory];

    if (codeSizeDirectory != null) {
      final File codeSizeFile = environment.fileSystem
        .directory(codeSizeDirectory)
        .childFile('snapshot.$_androidAbiName.json');
      final File precompilerTraceFile = environment.fileSystem
        .directory(codeSizeDirectory)
        .childFile('trace.$_androidAbiName.json');
      extraGenSnapshotOptions.add('--write-v8-snapshot-profile-to=${codeSizeFile.path}');
      extraGenSnapshotOptions.add('--trace-precompiler-to=${precompilerTraceFile.path}');
    }

    final String? splitDebugInfo = environment.defines[kSplitDebugInfo];
    final int snapshotExitCode = await snapshotter.build(
      platform: targetPlatform,
      buildMode: buildMode,
      mainPath: environment.buildDir.childFile('app.dill').path,
      outputPath: output.path,
      extraGenSnapshotOptions: extraGenSnapshotOptions,
      splitDebugInfo: splitDebugInfo,
      dartObfuscation: dartObfuscation,
    );
    if (snapshotExitCode != 0) {
      throw Exception('AOT snapshotter exited with code $snapshotExitCode');
    }
    if (environment.defines[kDeferredComponents] == 'true') {
      // Parse the manifest for .so paths
      final List<LoadingUnit> loadingUnits = LoadingUnit.parseLoadingUnitManifest(environment.fileSystem.file(manifestPath), environment.logger);
      for (final LoadingUnit unit in loadingUnits) {
        outputs.add(environment.fileSystem.file(unit.path));
      }
    }
    final DepfileService depfileService = DepfileService(
      fileSystem: environment.fileSystem,
      logger: environment.logger,
    );
    depfileService.writeToFile(
      Depfile(<File>[], outputs),
      environment.buildDir.childFile('flutter_$name.d'),
      writeEmpty: true,
    );
  }
}

// AndroidAot instances used by the bundle rules below.
const AndroidAot androidArmProfile = AndroidAot(TargetPlatform.android_arm,  BuildMode.profile);
const AndroidAot androidArm64Profile = AndroidAot(TargetPlatform.android_arm64, BuildMode.profile);
const AndroidAot androidx64Profile = AndroidAot(TargetPlatform.android_x64, BuildMode.profile);
const AndroidAot androidArmRelease = AndroidAot(TargetPlatform.android_arm,  BuildMode.release);
const AndroidAot androidArm64Release = AndroidAot(TargetPlatform.android_arm64, BuildMode.release);
const AndroidAot androidx64Release = AndroidAot(TargetPlatform.android_x64, BuildMode.release);

/// A rule paired with [AndroidAot] that copies the produced so file and manifest.json (if present) into the output directory.
class AndroidAotBundle extends Target {
  /// Create an [AndroidAotBundle] implementation for a given [targetPlatform] and [buildMode].
  const AndroidAotBundle(this.dependency);

  /// The [AndroidAot] instance this bundle rule depends on.
  final AndroidAot dependency;

  /// The name of the produced Android ABI.
  String get _androidAbiName {
    return getNameForAndroidArch(
      getAndroidArchForName(getNameForTargetPlatform(dependency.targetPlatform)));
  }

  @override
  String get name => 'android_aot_bundle_${getNameForBuildMode(dependency.buildMode)}_'
    '${getNameForTargetPlatform(dependency.targetPlatform)}';

  TargetPlatform get targetPlatform => dependency.targetPlatform;

  /// The selected build mode.
  ///
  /// This is restricted to [BuildMode.profile] or [BuildMode.release].
  BuildMode get buildMode => dependency.buildMode;

  @override
  List<Source> get inputs => <Source>[
    Source.pattern('{BUILD_DIR}/$_androidAbiName/app.so'),
  ];

  // flutter.gradle has been updated to correctly consume it.
  @override
  List<Source> get outputs => <Source>[
    Source.pattern('{OUTPUT_DIR}/$_androidAbiName/app.so'),
  ];

  @override
  List<String> get depfiles => <String>[
    'flutter_$name.d',
  ];

  @override
  List<Target> get dependencies => <Target>[
    dependency,
    const AotAndroidAssetBundle(),
  ];

  @override
  Future<void> build(Environment environment) async {
    final Directory buildDir = environment.buildDir.childDirectory(_androidAbiName);
    final Directory outputDirectory = environment.outputDir
      .childDirectory(_androidAbiName);
    if (!outputDirectory.existsSync()) {
      outputDirectory.createSync(recursive: true);
    }
    final File outputLibFile = buildDir.childFile('app.so');
    outputLibFile.copySync(outputDirectory.childFile('app.so').path);

    final List<File> inputs = <File>[];
    final List<File> outputs = <File>[];
    final File manifestFile = buildDir.childFile('manifest.json');
    if (manifestFile.existsSync()) {
      final File destinationFile = outputDirectory.childFile('manifest.json');
      manifestFile.copySync(destinationFile.path);
      inputs.add(manifestFile);
      outputs.add(destinationFile);
    }
    final DepfileService depfileService = DepfileService(
      fileSystem: environment.fileSystem,
      logger: environment.logger,
    );
    depfileService.writeToFile(
      Depfile(inputs, outputs),
      environment.buildDir.childFile('flutter_$name.d'),
      writeEmpty: true,
    );
  }
}

// AndroidBundleAot instances.
const AndroidAotBundle androidArmProfileBundle = AndroidAotBundle(androidArmProfile);
const AndroidAotBundle androidArm64ProfileBundle = AndroidAotBundle(androidArm64Profile);
const AndroidAotBundle androidx64ProfileBundle = AndroidAotBundle(androidx64Profile);
const AndroidAotBundle androidArmReleaseBundle = AndroidAotBundle(androidArmRelease);
const AndroidAotBundle androidArm64ReleaseBundle = AndroidAotBundle(androidArm64Release);
const AndroidAotBundle androidx64ReleaseBundle = AndroidAotBundle(androidx64Release);

// Rule that copies split aot library files to the intermediate dirs of each deferred component.
class AndroidAotDeferredComponentsBundle extends Target {
  /// Create an [AndroidAotDeferredComponentsBundle] implementation for a given [targetPlatform] and [buildMode].
  ///
  /// If [components] is not provided, it will be read from the pubspec.yaml manifest.
  AndroidAotDeferredComponentsBundle(this.dependency, {List<DeferredComponent>? components}) : _components = components;

  /// The [AndroidAotBundle] instance this bundle rule depends on.
  final AndroidAotBundle dependency;

  List<DeferredComponent>? _components;

  /// The name of the produced Android ABI.
  String get _androidAbiName {
    return getNameForAndroidArch(
      getAndroidArchForName(getNameForTargetPlatform(dependency.targetPlatform)));
  }

  @override
  String get name => 'android_aot_deferred_components_bundle_${getNameForBuildMode(dependency.buildMode)}_'
    '${getNameForTargetPlatform(dependency.targetPlatform)}';

  TargetPlatform get targetPlatform => dependency.targetPlatform;

  @override
  List<Source> get inputs => <Source>[
    // Tracking app.so is enough to invalidate the dynamically named
    // loading unit libs as changes to loading units guarantee
    // changes to app.so as well. This task does not actually
    // copy app.so.
    Source.pattern('{OUTPUT_DIR}/$_androidAbiName/app.so'),
    const Source.pattern('{PROJECT_DIR}/pubspec.yaml'),
  ];

  @override
  List<Source> get outputs => const <Source>[];

  @override
  List<String> get depfiles => <String>[
    'flutter_$name.d',
  ];

  @override
  List<Target> get dependencies => <Target>[
    dependency,
  ];

  @override
  Future<void> build(Environment environment) async {
    _components ??= FlutterProject.current().manifest.deferredComponents ?? <DeferredComponent>[];
    final List<String> abis = <String>[_androidAbiName];
    final List<LoadingUnit> generatedLoadingUnits = LoadingUnit.parseGeneratedLoadingUnits(environment.outputDir, environment.logger, abis: abis);
    for (final DeferredComponent component in _components!) {
      component.assignLoadingUnits(generatedLoadingUnits);
    }
    final Depfile libDepfile = copyDeferredComponentSoFiles(environment, _components!, generatedLoadingUnits, environment.projectDir.childDirectory('build'), abis, dependency.buildMode);

    final File manifestFile = environment.outputDir.childDirectory(_androidAbiName).childFile('manifest.json');
    if (manifestFile.existsSync()) {
      libDepfile.inputs.add(manifestFile);
    }

    final DepfileService depfileService = DepfileService(
      fileSystem: environment.fileSystem,
      logger: environment.logger,
    );
    depfileService.writeToFile(
      libDepfile,
      environment.buildDir.childFile('flutter_$name.d'),
      writeEmpty: true,
    );
  }
}

Target androidArmProfileDeferredComponentsBundle = AndroidAotDeferredComponentsBundle(androidArmProfileBundle);
Target androidArm64ProfileDeferredComponentsBundle = AndroidAotDeferredComponentsBundle(androidArm64ProfileBundle);
Target androidx64ProfileDeferredComponentsBundle = AndroidAotDeferredComponentsBundle(androidx64ProfileBundle);
Target androidArmReleaseDeferredComponentsBundle = AndroidAotDeferredComponentsBundle(androidArmReleaseBundle);
Target androidArm64ReleaseDeferredComponentsBundle = AndroidAotDeferredComponentsBundle(androidArm64ReleaseBundle);
Target androidx64ReleaseDeferredComponentsBundle = AndroidAotDeferredComponentsBundle(androidx64ReleaseBundle);

/// A set of all target names that build deferred component apps.
Set<String> deferredComponentsTargets = <String>{
  androidArmProfileDeferredComponentsBundle.name,
  androidArm64ProfileDeferredComponentsBundle.name,
  androidx64ProfileDeferredComponentsBundle.name,
  androidArmReleaseDeferredComponentsBundle.name,
  androidArm64ReleaseDeferredComponentsBundle.name,
  androidx64ReleaseDeferredComponentsBundle.name,
};

/// Utility method to copy and rename the required .so shared libs from the build output
/// to the correct component intermediate directory.
///
/// The [DeferredComponent]s passed to this method must have had loading units assigned.
/// Assigned components are components that have determined which loading units contains
/// the dart libraries it has via the DeferredComponent.assignLoadingUnits method.
Depfile copyDeferredComponentSoFiles(
  Environment env,
  List<DeferredComponent> components,
  List<LoadingUnit> loadingUnits,
  Directory buildDir, // generally `<projectDir>/build`
  List<String> abis,
  BuildMode buildMode,
) {
  final List<File> inputs = <File>[];
  final List<File> outputs = <File>[];
  final Set<int> usedLoadingUnits = <int>{};
  // Copy all .so files for loading units that are paired with a deferred component.
  for (final String abi in abis) {
    for (final DeferredComponent component in components) {
      final Set<LoadingUnit>? loadingUnits = component.loadingUnits;
      if (loadingUnits == null || !component.assigned) {
        env.logger.printError('Deferred component require loading units to be assigned.');
        return Depfile(inputs, outputs);
      }
      for (final LoadingUnit unit in loadingUnits) {
        // ensure the abi for the unit is one of the abis we build for.
        final List<String>? splitPath = unit.path?.split(env.fileSystem.path.separator);
        if (splitPath == null || splitPath[splitPath.length - 2] != abi) {
          continue;
        }
        usedLoadingUnits.add(unit.id);
        // the deferred_libs directory is added as a source set for the component.
        final File destination = buildDir
            .childDirectory(component.name)
            .childDirectory('intermediates')
            .childDirectory('flutter')
            .childDirectory(buildMode.name)
            .childDirectory('deferred_libs')
            .childDirectory(abi)
            .childFile('libapp.so-${unit.id}.part.so');
        if (!destination.existsSync()) {
          destination.createSync(recursive: true);
        }
        final File source = env.fileSystem.file(unit.path);
        source.copySync(destination.path);
        inputs.add(source);
        outputs.add(destination);
      }
    }
  }
  // Copy unused loading units, which are included in the base module.
  for (final String abi in abis) {
    for (final LoadingUnit unit in loadingUnits) {
      if (usedLoadingUnits.contains(unit.id)) {
        continue;
      }
        // ensure the abi for the unit is one of the abis we build for.
      final List<String>? splitPath = unit.path?.split(env.fileSystem.path.separator);
      if (splitPath == null || splitPath[splitPath.length - 2] != abi) {
        continue;
      }
      final File destination = env.outputDir
          .childDirectory(abi)
          // Omit 'lib' prefix here as it is added by the gradle task that adds 'lib' to 'app.so'.
          .childFile('app.so-${unit.id}.part.so');
      if (!destination.existsSync()) {
          destination.createSync(recursive: true);
        }
      final File source = env.fileSystem.file(unit.path);
      source.copySync(destination.path);
      inputs.add(source);
      outputs.add(destination);
    }
  }
  return Depfile(inputs, outputs);
}
