// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:dev_compiler/src/command/command.dart'
    show addGeneratedVariables;
import 'package:dev_compiler/src/compiler/module_builder.dart'
    show ModuleFormat;
import 'package:dev_compiler/src/kernel/target.dart' show DevCompilerTarget;
import 'package:front_end/src/api_unstable/ddc.dart' as fe;
import 'package:kernel/ast.dart' show Component;
import 'package:kernel/target/targets.dart' show TargetFlags;

class DevelopmentIncrementalCompiler extends fe.IncrementalCompiler {
  Uri entryPoint;

  DevelopmentIncrementalCompiler(
    fe.CompilerOptions options,
    this.entryPoint, [
    Uri? initializeFrom,
    bool? outlineOnly,
    fe.IncrementalSerializer? incrementalSerializer,
  ]) : super(
         fe.CompilerContext(
           fe.ProcessedOptions(options: options, inputs: [entryPoint]),
         ),
         initializeFrom,
         outlineOnly,
         incrementalSerializer,
       );

  DevelopmentIncrementalCompiler.fromComponent(
    fe.CompilerOptions options,
    this.entryPoint,
    Component componentToInitializeFrom, [
    bool? outlineOnly,
    fe.IncrementalSerializer? incrementalSerializer,
  ]) : super.fromComponent(
         fe.CompilerContext(
           fe.ProcessedOptions(options: options, inputs: [entryPoint]),
         ),
         componentToInitializeFrom,
         outlineOnly,
         incrementalSerializer,
       );
}

class SetupCompilerOptions {
  static final sdkRoot = fe.computePlatformBinariesLocation();
  static final buildRoot = fe.computePlatformBinariesLocation(
    forceBuildDir: true,
  );

  final List<String> errors = [];
  final List<String> diagnosticMessages = [];
  final ModuleFormat moduleFormat;
  final fe.CompilerOptions options;
  final bool canaryFeatures;
  final bool enableAsserts;

  static fe.CompilerOptions _getOptions({
    required bool enableAsserts,
    required List<String> enableExperiments,
  }) {
    var options = fe.CompilerOptions()
      ..verbose =
          false // set to true for debugging
      ..sdkRoot = sdkRoot
      ..target = DevCompilerTarget(TargetFlags())
      ..omitPlatform = true
      ..sdkSummary = buildRoot.resolve('ddc_outline.dill')
      ..environmentDefines = addGeneratedVariables(
        {},
        enableAsserts: enableAsserts,
      )
      ..explicitExperimentalFlags = fe.parseExperimentalFlags(
        fe.parseExperimentalArguments(enableExperiments),
        onError: (e) => throw e,
      );
    return options;
  }

  SetupCompilerOptions._({
    this.enableAsserts = true,
    this.moduleFormat = ModuleFormat.amd,
    this.canaryFeatures = false,
    List<String> enableExperiments = const [],
  }) : options = _getOptions(
         enableAsserts: enableAsserts,
         enableExperiments: enableExperiments,
       ) {
    options.onDiagnostic = (fe.CfeDiagnosticMessage m) {
      diagnosticMessages.addAll(m.plainTextFormatted);
      if (m.severity == fe.CfeSeverity.error ||
          m.severity == fe.CfeSeverity.internalProblem) {
        errors.addAll(m.plainTextFormatted);
      }
    };
  }

  /// Creates current compiler setup options.
  ///
  /// Reads options determined by the test configuration from the configuration
  /// environment variable set by the test runner.
  ///
  /// To run tests locally using test.py, pass a vm option defining required
  /// configuration, for example:
  ///
  /// `./tools/test.py -n web-dev-canary-unittest-asserts-mac`
  ///
  /// To run a single test locally, pass the --canary or --enable-asserts flags
  /// to the command line to enable corresponding features, for example:
  ///
  /// `dart test/expression_compiler/assertions_enabled_test.dart --canary --enable-asserts`
  factory SetupCompilerOptions({
    ModuleFormat moduleFormat = ModuleFormat.amd,
    List<String> enableExperiments = const [],
    List<String> args = const [],
  }) {
    // Find if the test is run with arguments overriding the configuration
    late bool enableAsserts;
    late bool canaryFeatures;

    // Read configuration settings from matrix.json
    var configuration = String.fromEnvironment('test_runner.configuration');
    if (configuration.isEmpty) {
      // If not running from test runner, read options from the args
      enableAsserts = args.contains('--enable-asserts');
      canaryFeatures = args.contains('--canary');
    } else {
      // If running from the test runner, read options from the environment
      // (set to configuration settings from matrix.json).
      enableAsserts = configuration.contains('-asserts-');
      canaryFeatures = configuration.contains('-canary-');
    }
    return SetupCompilerOptions._(
      enableAsserts: enableAsserts,
      moduleFormat: moduleFormat,
      canaryFeatures: canaryFeatures,
      enableExperiments: enableExperiments,
    );
  }

  bool get emitLibraryBundle =>
      canaryFeatures && moduleFormat == ModuleFormat.ddc;
}
