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

import 'package:meta/meta.dart';

import 'base/common.dart';
import 'base/logger.dart';
import 'build_info.dart';
import 'build_system/build_system.dart';
import 'build_system/targets/dart.dart';
import 'build_system/targets/icon_tree_shaker.dart';
import 'build_system/targets/ios.dart';
import 'cache.dart';
import 'convert.dart';
import 'globals.dart' as globals;
import 'ios/bitcode.dart';
import 'project.dart';

/// Builds AOT snapshots given a platform, build mode and a path to a Dart
/// library.
class AotBuilder {
  Future<void> build({
    @required TargetPlatform platform,
    @required String outputPath,
    @required BuildInfo buildInfo,
    @required String mainDartFile,
    bool bitcode = kBitcodeEnabledDefault,
    bool quiet = true,
    Iterable<DarwinArch> iosBuildArchs = defaultIOSArchs,
    bool reportTimings = false,
  }) async {
    if (platform == null) {
      throwToolExit('No AOT build platform specified');
    }
    Target target;
    bool expectSo = false;
    switch (platform) {
      case TargetPlatform.android:
      case TargetPlatform.darwin_x64:
      case TargetPlatform.linux_x64:
      case TargetPlatform.windows_x64:
      case TargetPlatform.fuchsia_arm64:
      case TargetPlatform.tester:
      case TargetPlatform.web_javascript:
      case TargetPlatform.android_x86:
        throwToolExit('$platform is not supported in AOT.');
        break;
      case TargetPlatform.fuchsia_x64:
        throwToolExit(
          "To build release for fuchsia, use 'flutter build fuchsia --release'"
        );
        break;
      case TargetPlatform.ios:
        target = buildInfo.isRelease
          ? const AotAssemblyRelease()
          : const AotAssemblyProfile();
        break;
      case TargetPlatform.android_arm:
      case TargetPlatform.android_arm64:
      case TargetPlatform.android_x64:
        expectSo = true;
        target = buildInfo.isRelease
          ? const AotElfRelease()
          : const AotElfProfile();
    }

    Status status;
    if (!quiet) {
      final String typeName = globals.artifacts.getEngineType(platform, buildInfo.mode);
      status = globals.logger.startProgress(
        'Building AOT snapshot in ${getFriendlyModeName(buildInfo.mode)} mode ($typeName)...',
        timeout: timeoutConfiguration.slowOperation,
      );
    }

    final Environment environment = Environment(
      projectDir: globals.fs.currentDirectory,
      outputDir: globals.fs.directory(outputPath),
      buildDir: FlutterProject.current().dartTool.childDirectory('flutter_build'),
      cacheDir: null,
      flutterRootDir: globals.fs.directory(Cache.flutterRoot),
      defines: <String, String>{
        kTargetFile: mainDartFile ?? globals.fs.path.join('lib', 'main.dart'),
        kBuildMode: getNameForBuildMode(buildInfo.mode),
        kTargetPlatform: getNameForTargetPlatform(platform),
        kIconTreeShakerFlag: buildInfo.treeShakeIcons.toString(),
        kDartDefines: jsonEncode(buildInfo.dartDefines),
        kBitcodeFlag: bitcode.toString(),
        if (buildInfo?.extraGenSnapshotOptions?.isNotEmpty ?? false)
          kExtraGenSnapshotOptions: buildInfo.extraGenSnapshotOptions.join(','),
        if (buildInfo?.extraFrontEndOptions?.isNotEmpty ?? false)
          kExtraFrontEndOptions: buildInfo.extraFrontEndOptions.join(','),
        if (platform == TargetPlatform.ios)
          kIosArchs: iosBuildArchs.map(getNameForDarwinArch).join(' ')
      },
      artifacts: globals.artifacts,
      fileSystem: globals.fs,
      logger: globals.logger,
      processManager: globals.processManager,
    );
    final BuildResult result = await globals.buildSystem.build(target, environment);
    status?.stop();

    if (!result.success) {
      for (final ExceptionMeasurement measurement in result.exceptions.values) {
        globals.printError(measurement.exception.toString());
      }
      throwToolExit('The aot build failed.');
    }

    // This print output is used by the dart team for build benchmarks.
    if (reportTimings) {
      final PerformanceMeasurement kernel = result.performance['kernel_snapshot'];
      PerformanceMeasurement aot;
      if (expectSo) {
        aot = result.performance.values.firstWhere(
          (PerformanceMeasurement measurement) => measurement.analyicsName == 'android_aot');
      } else {
        aot = result.performance.values.firstWhere(
          (PerformanceMeasurement measurement) => measurement.analyicsName == 'ios_aot');
      }
      globals.printStatus('frontend(CompileTime): ${kernel.elapsedMilliseconds} ms.');
      globals.printStatus('snapshot(CompileTime): ${aot.elapsedMilliseconds} ms.');
    }

    if (expectSo) {
      environment.buildDir.childFile('app.so')
        .copySync(globals.fs.path.join(outputPath, 'app.so'));
    } else {
      globals.fs.directory(globals.fs.path.join(outputPath, 'App.framework'))
        .createSync(recursive: true);
      environment.buildDir.childDirectory('App.framework').childFile('App')
        .copySync(globals.fs.path.join(outputPath, 'App.framework', 'App'));
    }

    final String builtMessage = 'Built to $outputPath${globals.fs.path.separator}.';
    if (quiet) {
      globals.printTrace(builtMessage);
    } else {
      globals.printStatus(builtMessage);
    }
    return;
  }
}
