// Copyright (c) 2020, 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 'dart:io' show File;
import 'dart:typed_data' show Uint8List;

import 'package:_fe_analyzer_shared/src/messages/codes.dart';
import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
import 'package:dev_compiler/src/kernel/target.dart' show DevCompilerTarget;
import 'package:front_end/src/api_prototype/compiler_options.dart'
    show CompilerOptions, DiagnosticMessage;
import 'package:front_end/src/api_prototype/experimental_flags.dart'
    show ExperimentalFlag;
import 'package:front_end/src/base/compiler_context.dart' show CompilerContext;
import 'package:front_end/src/base/incremental_compiler.dart'
    show IncrementalCompiler;
import 'package:front_end/src/base/problems.dart';
import 'package:front_end/src/base/processed_options.dart'
    show ProcessedOptions;
import 'package:front_end/src/kernel/constant_evaluator.dart' as constants
    show EvaluationMode, transformLibraries, ErrorReporter;
import 'package:front_end/src/kernel/kernel_target.dart';
import 'package:front_end/src/kernel/utils.dart' show serializeComponent;
import 'package:kernel/ast.dart';
import 'package:kernel/binary/ast_from_binary.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/target/changed_structure_notifier.dart';
import 'package:kernel/target/targets.dart'
    show DiagnosticReporter, Target, TargetFlags;
import 'package:kernel/type_environment.dart';
import "package:vm/modular/target/flutter.dart" show FlutterTarget;
import "package:vm/modular/target/vm.dart" show VmTarget;

import 'incremental_suite.dart' show getOptions;

bool? tryWithNoEnvironment;
bool verbose = false;
bool skipNonNullEnvironment = false;
bool skipNullEnvironment = false;

void benchmark(Component component, List<Library> libraries) {
  if (tryWithNoEnvironment == null) throw "tryWithNoEnvironment not set";
  KernelTarget target = incrementalCompiler.kernelTargetForTesting!;
  constants.EvaluationMode evaluationMode =
      target.getConstantEvaluationModeForTesting();

  Uint8List serializedComponent = serializeComponent(component);

  for (int k = 0; k < 3; k++) {
    Map<String, String>? environmentDefines = null;
    String environmentDefinesDescription = "null environment";

    for (int j = 0; j < 2; j++) {
      Stopwatch stopwatch = new Stopwatch()..start();
      int iterations = 0;
      int sum = 0;
      for (int i = 0; i < 5; i++) {
        if (!tryWithNoEnvironment! && environmentDefines == null) continue;
        if (skipNullEnvironment && environmentDefines == null) continue;
        if (skipNonNullEnvironment && environmentDefines != null) continue;
        stopwatch.reset();
        Component component = new Component();
        BinaryBuilder binaryBuilder = new BinaryBuilder(serializedComponent,
            disableLazyClassReading: true, disableLazyReading: true);
        binaryBuilder.readComponent(component);
        if (verbose) {
          print("Loaded component in ${stopwatch.elapsedMilliseconds} ms");
        }

        stopwatch.reset();
        CoreTypes coreTypes = new CoreTypes(component);
        ClassHierarchy hierarchy = new ClassHierarchy(component, coreTypes);
        TypeEnvironment environment = new TypeEnvironment(coreTypes, hierarchy);
        if (verbose) {
          print("Created core types and class hierarchy"
              " in ${stopwatch.elapsedMilliseconds} ms");
        }

        stopwatch.reset();
        constants.transformLibraries(
            component,
            component.libraries,
            target.backendTarget,
            environmentDefines,
            environment,
            new SilentErrorReporter(),
            evaluationMode,
            evaluateAnnotations: true,
            enableTripleShift: target.globalFeatures.tripleShift.isEnabled,
            enableConstFunctions:
                target.globalFeatures.constFunctions.isEnabled,
            enableConstructorTearOff:
                target.globalFeatures.constructorTearoffs.isEnabled,
            errorOnUnevaluatedConstant:
                incrementalCompiler.context.options.errorOnUnevaluatedConstant);
        print("Transformed constants with $environmentDefinesDescription"
            " in ${stopwatch.elapsedMilliseconds} ms");
        sum += stopwatch.elapsedMilliseconds;
        iterations++;
      }
      if (verbose) {
        print("With $environmentDefinesDescription: "
            "Did constant evaluation $iterations iterations in $sum ms,"
            " i.e. an average of ${sum / iterations} ms per iteration.");
      }
      environmentDefines = {};
      environmentDefinesDescription = "empty environment";
    }
  }
}

class SilentErrorReporter implements constants.ErrorReporter {
  @override
  bool get supportsTrackingReportedErrors => false;

  @override
  bool get hasSeenError {
    return unsupported("SilentErrorReporter.hasSeenError", -1, null);
  }

  @override
  void report(LocatedMessage message, [List<LocatedMessage>? context]) {
    // ignore
  }
}

late IncrementalCompiler incrementalCompiler;

Future<void> main(List<String> arguments) async {
  Uri? platformUri;
  Uri mainUri;
  bool nnbd = false;
  String targetString = "VM";

  String? filename;
  for (String arg in arguments) {
    if (arg.startsWith("--")) {
      if (arg == "--nnbd") {
        nnbd = true;
      } else if (arg.startsWith("--platform=")) {
        String platform = arg.substring("--platform=".length);
        platformUri = Uri.base.resolve(platform);
      } else if (arg == "--target=VM") {
        targetString = "VM";
      } else if (arg == "--target=flutter") {
        targetString = "flutter";
      } else if (arg == "--target=ddc") {
        targetString = "ddc";
      } else if (arg == "--target=dart2js") {
        targetString = "dart2js";
      } else if (arg == "-v") {
        verbose = true;
      } else if (arg == "--skip-null-environment") {
        skipNullEnvironment = true;
      } else if (arg == "--skip-non-null-environment") {
        skipNonNullEnvironment = true;
      } else {
        throw "Unknown option $arg";
      }
    } else if (filename != null) {
      throw "Already got '$filename', '$arg' is also a filename; "
          "can only get one";
    } else {
      filename = arg;
    }
  }

  if (platformUri == null) {
    throw "No platform given. Use --platform=/path/to/platform.dill";
  }
  if (!new File.fromUri(platformUri).existsSync()) {
    throw "The platform file '$platformUri' doesn't exist";
  }
  if (filename == null) {
    throw "Need file to operate on";
  }
  File file = new File(filename);
  if (!file.existsSync()) throw "File $filename doesn't exist.";
  mainUri = file.absolute.uri;

  incrementalCompiler = new IncrementalCompiler(
      setupCompilerContext(nnbd, targetString, false, platformUri, mainUri));
  await incrementalCompiler.computeDelta();
}

CompilerContext setupCompilerContext(bool nnbd, String targetString,
    bool widgetTransformation, Uri platformUri, Uri mainUri) {
  CompilerOptions options = getOptions();

  if (nnbd) {
    options.explicitExperimentalFlags = {ExperimentalFlag.nonNullable: true};
  }

  TargetFlags targetFlags = new TargetFlags(
      soundNullSafety: nnbd, trackWidgetCreation: widgetTransformation);
  Target target;
  switch (targetString) {
    case "VM":
      target = new HookInVmTarget(targetFlags);
      tryWithNoEnvironment = false;
      break;
    case "flutter":
      target = new HookInFlutterTarget(targetFlags);
      tryWithNoEnvironment = false;
      break;
    case "ddc":
      target = new HookInDevCompilerTarget(targetFlags);
      tryWithNoEnvironment = false;
      break;
    case "dart2js":
      target = new HookInDart2jsTarget("dart2js", targetFlags);
      tryWithNoEnvironment = true;
      break;
    default:
      throw "Unknown target '$targetString'";
  }
  options.target = target;
  options.sdkRoot = null;
  options.sdkSummary = platformUri;
  options.omitPlatform = false;
  options.onDiagnostic = (DiagnosticMessage message) {
    // don't care.
  };

  ProcessedOptions processedOptions =
      new ProcessedOptions(options: options, inputs: [mainUri]);
  CompilerContext compilerContext = new CompilerContext(processedOptions);
  return compilerContext;
}

class HookInVmTarget extends VmTarget {
  HookInVmTarget(TargetFlags flags) : super(flags);

  @override
  void performPreConstantEvaluationTransformations(
      Component component,
      CoreTypes coreTypes,
      List<Library> libraries,
      DiagnosticReporter diagnosticReporter,
      {void Function(String msg)? logger,
      ChangedStructureNotifier? changedStructureNotifier}) {
    super.performPreConstantEvaluationTransformations(
        component, coreTypes, libraries, diagnosticReporter,
        logger: logger, changedStructureNotifier: changedStructureNotifier);
    benchmark(component, libraries);
  }
}

class HookInDart2jsTarget extends Dart2jsTarget {
  HookInDart2jsTarget(String name, TargetFlags flags) : super(name, flags);

  @override
  void performPreConstantEvaluationTransformations(
      Component component,
      CoreTypes coreTypes,
      List<Library> libraries,
      DiagnosticReporter diagnosticReporter,
      {void Function(String msg)? logger,
      ChangedStructureNotifier? changedStructureNotifier}) {
    super.performPreConstantEvaluationTransformations(
        component, coreTypes, libraries, diagnosticReporter,
        logger: logger, changedStructureNotifier: changedStructureNotifier);
    benchmark(component, libraries);
  }
}

class HookInDevCompilerTarget extends DevCompilerTarget {
  HookInDevCompilerTarget(TargetFlags flags) : super(flags);

  @override
  void performPreConstantEvaluationTransformations(
      Component component,
      CoreTypes coreTypes,
      List<Library> libraries,
      DiagnosticReporter diagnosticReporter,
      {void Function(String msg)? logger,
      ChangedStructureNotifier? changedStructureNotifier}) {
    super.performPreConstantEvaluationTransformations(
        component, coreTypes, libraries, diagnosticReporter,
        logger: logger, changedStructureNotifier: changedStructureNotifier);
    benchmark(component, libraries);
  }
}

class HookInFlutterTarget extends FlutterTarget {
  HookInFlutterTarget(TargetFlags flags) : super(flags);

  @override
  void performPreConstantEvaluationTransformations(
      Component component,
      CoreTypes coreTypes,
      List<Library> libraries,
      DiagnosticReporter diagnosticReporter,
      {void Function(String msg)? logger,
      ChangedStructureNotifier? changedStructureNotifier}) {
    super.performPreConstantEvaluationTransformations(
        component, coreTypes, libraries, diagnosticReporter,
        logger: logger, changedStructureNotifier: changedStructureNotifier);
    benchmark(component, libraries);
  }
}
