// 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/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 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!;

  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(),
            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;
  String targetString = "VM";

  String? filename;
  for (String arg in arguments) {
    if (arg.startsWith("--")) {
      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(targetString, false, platformUri, mainUri));
  await incrementalCompiler.computeDelta();
}

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

  TargetFlags targetFlags =
      new TargetFlags(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);
  }
}
