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