// Copyright (c) 2016, 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:convert' show JsonEncoder, LineSplitter, jsonDecode, utf8;
import 'dart:io'
    show File, Platform, ProcessSignal, exit, exitCode, stderr, stdin, stdout;

import 'package:_fe_analyzer_shared/src/util/relativize.dart'
    show isWindows, relativizeUri;
import 'package:front_end/src/api_prototype/compiler_options.dart'
    show CompilerOptions, CfeDiagnosticMessage;
import 'package:front_end/src/api_prototype/incremental_kernel_generator.dart';
import 'package:front_end/src/api_prototype/kernel_generator.dart';
import 'package:front_end/src/base/command_line_options.dart';
import 'package:front_end/src/base/compiler_context.dart' show CompilerContext;
import 'package:front_end/src/base/file_system_dependency_tracker.dart';
import 'package:front_end/src/base/get_dependencies.dart' show getDependencies;
import 'package:front_end/src/base/incremental_compiler.dart'
    show IncrementalCompiler;
import 'package:front_end/src/base/processed_options.dart'
    show ProcessedOptions;
import 'package:front_end/src/codes/cfe_codes.dart'
    show codeInternalProblemVerificationError;
import 'package:front_end/src/kernel/benchmarker.dart'
    show BenchmarkPhases, Benchmarker;
import 'package:front_end/src/kernel/utils.dart' show writeComponentToFile;
import 'package:front_end/src/kernel_generator_impl.dart'
    show generateKernelInternal;
import 'package:front_end/src/linux_and_intel_specific_perf.dart';
import 'package:kernel/kernel.dart'
    show Component, Library, RecursiveVisitor, Source;
import 'package:kernel/src/types.dart' show Types;
import 'package:kernel/target/targets.dart' show Target, TargetFlags, getTarget;
import 'package:kernel/verifier.dart';

import '../test/coverage_helper.dart';
import 'additional_targets.dart' show installAdditionalTargets;
import 'bench_maker.dart' show BenchMaker;
import 'command_line.dart' show runProtectedFromAbort, withGlobalOptions;

const bool benchmark = const bool.fromEnvironment(
  "benchmark",
  defaultValue: false,
);

const bool summary =
    const bool.fromEnvironment("summary", defaultValue: false) || benchmark;

const int iterations = const int.fromEnvironment("iterations", defaultValue: 1);

Future<void> compileEntryPoint(List<String> arguments) async {
  if (Platform.environment["dart_cfe_intel_pt"] == "true") {
    print("Notice: Locating perf for profiling using intel_pt events.");
    linuxAndIntelSpecificPerf(onlyInitialize: true);
  }
  installAdditionalTargets();

  // Timing results for each iteration
  List<double> elapsedTimes = <double>[];
  List<Benchmarker> benchmarkers = <Benchmarker>[];

  for (int i = 0; i < iterations; i++) {
    if (i > 0) {
      print("\n\n=== Iteration ${i + 1} of $iterations");
    }
    Stopwatch stopwatch = new Stopwatch()..start();
    Benchmarker? benchmarker;
    if (benchmark) {
      benchmarker = new Benchmarker();
      benchmarkers.add(benchmarker);
    }
    await compile(arguments, benchmarker: benchmarker);
    benchmarker?.stop();
    stopwatch.stop();

    elapsedTimes.add(stopwatch.elapsedMilliseconds.toDouble());
    List<Object>? typeChecks = Types.typeChecksForTesting;
    if (typeChecks?.isNotEmpty ?? false) {
      BenchMaker.writeTypeChecks("type_checks.json", typeChecks!);
    }
  }

  summarize(elapsedTimes, benchmarkers);
}

Future<void> outlineEntryPoint(List<String> arguments) async {
  installAdditionalTargets();

  // Timing results for each iteration
  List<double> elapsedTimes = <double>[];
  List<Benchmarker> benchmarkers = <Benchmarker>[];

  for (int i = 0; i < iterations; i++) {
    if (i > 0) {
      print("\n\n=== Iteration ${i + 1} of $iterations");
    }
    Stopwatch stopwatch = new Stopwatch()..start();
    Benchmarker? benchmarker;
    if (benchmark) {
      benchmarker = new Benchmarker();
      benchmarkers.add(benchmarker);
    }
    await outline(arguments, benchmarker: benchmarker);
    benchmarker?.stop();
    stopwatch.stop();

    elapsedTimes.add(stopwatch.elapsedMilliseconds.toDouble());
  }

  summarize(elapsedTimes, benchmarkers);
}

void summarize(List<double> elapsedTimes, List<Benchmarker> benchmarkers) {
  if (summary) {
    Map<String, dynamic> map = <String, dynamic>{
      'elapsedTimes': elapsedTimes,
      if (benchmarkers.isNotEmpty) 'benchmarkers': benchmarkers,
    };
    JsonEncoder encoder = new JsonEncoder.withIndent("  ");
    String json = encoder.convert(map);
    print('\nSummary:\n\n$json\n');
  } else {
    assert(benchmarkers.isEmpty);
  }
}

Future<void> depsEntryPoint(List<String> arguments) async {
  installAdditionalTargets();

  for (int i = 0; i < iterations; i++) {
    if (i > 1) {
      print("\n");
    }
    await deps(arguments);
  }
}

Future<void> compilePlatformEntryPoint(List<String> arguments) async {
  installAdditionalTargets();
  for (int i = 0; i < iterations; i++) {
    if (i > 0) {
      print("\n");
    }
    await runProtectedFromAbort<void>(() => compilePlatform(arguments));
  }
}

Future<void> batchEntryPoint(List<String> arguments) async {
  if (shouldCollectCoverage()) {
    tryListenToSignal(
      ProcessSignal.sigterm,
      () => possiblyCollectCoverage("batch_compiler", doExit: true),
    );
  }
  installAdditionalTargets();
  await new BatchCompiler(
    stdin.transform(utf8.decoder).transform(new LineSplitter()),
  ).run();
}

void tryListenToSignal(ProcessSignal signal, void Function() callback) {
  try {
    signal.watch().listen(
      (_) => callback(),
      onError: (_) {
        // swallow.
      },
    );
  } catch (e) {
    // swallow.
  }
}

const String cfeCoverageEnvironmentVariable = "CFE_COVERAGE";

bool shouldCollectCoverage() {
  String? coverage = Platform.environment[cfeCoverageEnvironmentVariable];
  if (coverage != null) return true;
  return false;
}

Future<void> possiblyCollectCoverage(
  String displayNamePrefix, {
  required bool doExit,
}) async {
  String? coverage = Platform.environment[cfeCoverageEnvironmentVariable];

  if (coverage != null) {
    assert(shouldCollectCoverage());
    Uri coverageUri = Uri.base.resolveUri(Uri.file(coverage));
    String displayName =
        "${displayNamePrefix}_${DateTime.now().microsecondsSinceEpoch}";
    File f = new File.fromUri(coverageUri.resolve("$displayName.coverage"));
    // Force compiling seems to add something like 1 second to the collection
    // time, but we get rid of uncompiled functions so it seems to be worth it.
    (await collectCoverage(
      displayName: displayName,
      forceCompile: true,
    ))?.writeToFile(f);
  }

  if (doExit) {
    exit(exitCode);
  }
}

class BatchCompiler {
  final Stream<String>? lines;

  Uri? platformUri;

  Component? platformComponent;

  bool hadVerifyError = false;

  IncrementalCompiler? _incrementalCompiler;

  List<CfeDiagnosticMessage> _errors = [];

  void Function(CfeDiagnosticMessage)? _originalOnDiagnostic;

  BatchCompiler(this.lines);

  Future<void> run() async {
    await for (String line in lines!) {
      try {
        if (await batchCompileArguments(
          new List<String>.from(jsonDecode(line)),
        )) {
          stdout.writeln(">>> TEST OK");
        } else {
          stdout.writeln(">>> TEST FAIL");
        }
      } catch (e, trace) {
        stderr.writeln("Unhandled exception:\n  $e");
        stderr.writeln(trace);
        stdout.writeln(">>> TEST CRASH");
        _incrementalCompiler = null;
      }
      await stdout.flush();
      stderr.writeln(">>> EOF STDERR");
      await stderr.flush();
    }
  }

  Future<bool> batchCompileArguments(List<String> arguments) {
    return runProtectedFromAbort<bool>(
      () => withGlobalOptions<bool>(
        "compile",
        [Flags.omitPlatform, ...arguments],
        true,
        (CompilerContext c, _) => batchCompileImpl(c),
      ),
      false,
    );
  }

  Future<bool> batchCompile(CompilerOptions options, Uri input, Uri output) {
    return CompilerContext.runWithOptions(
      new ProcessedOptions(
        options: options,
        inputs: <Uri>[input],
        output: output,
      ),
      batchCompileImpl,
    );
  }

  void _onDiagnostic(CfeDiagnosticMessage message) {
    _errors.add(message);
    if (_originalOnDiagnostic != null) {
      _originalOnDiagnostic!(message);
    }
  }

  Future<bool> batchCompileImpl(CompilerContext context) async {
    _errors.clear();
    ProcessedOptions options = context.options;
    bool createNewCompiler = false;
    if (_incrementalCompiler == null ||
        !_incrementalCompiler!.context.options.equivalent(options)) {
      createNewCompiler = true;
    }

    if (platformComponent == null ||
        platformUri != options.sdkSummary ||
        hadVerifyError) {
      createNewCompiler = true;
      platformUri = options.sdkSummary;
      platformComponent = await options.loadSdkSummary(null);
      if (platformComponent == null) {
        throw "platformComponent is null";
      }
      hadVerifyError = false;
    }

    if (createNewCompiler) {
      platformComponent!.adoptChildren();
      _incrementalCompiler = new IncrementalCompiler.fromComponent(
        context,
        platformComponent,
      );
    }

    ProcessedOptions incrementalCompilerOptions =
        _incrementalCompiler!.context.options;
    if (!identical(incrementalCompilerOptions.inputs, options.inputs)) {
      // Invalidating the packages uri causes it to recalculate which packages
      // file to use which is what we want.
      _incrementalCompiler!.invalidate(incrementalCompilerOptions.packagesUri);
      incrementalCompilerOptions.inputs.clear();
      incrementalCompilerOptions.inputs.addAll(options.inputs);
    }

    _originalOnDiagnostic =
        options.rawOptionsForTesting.onDiagnostic ??
        options.defaultDiagnosticMessageHandler;
    incrementalCompilerOptions.rawOptionsForTesting.onDiagnostic =
        _onDiagnostic;

    assert(
      options.omitPlatform,
      "Platform must be omitted for the batch compiler.",
    );
    assert(
      !options.hasAdditionalDills,
      "Additional dills are not supported for the batch compiler.",
    );
    IncrementalCompilerResult compilerResult = await _incrementalCompiler!
        .computeDelta(fullComponent: true);
    await _emitComponent(
      options,
      compilerResult.component,
      message: "Wrote component to ",
    );
    for (CfeDiagnosticMessage error in _errors) {
      if (error.codeName == codeInternalProblemVerificationError.name) {
        hadVerifyError = true;
      }
    }
    return _errors.isEmpty;
  }
}

Future<void> incrementalEntryPoint(List<String> arguments) async {
  installAdditionalTargets();
  await withGlobalOptions("incremental", arguments, true, (
    CompilerContext c,
    _,
  ) {
    // TODO(ahe): Extend this entry point so it can replace
    // batchEntryPoint.
    new IncrementalCompiler(c);
    return Future<void>.value();
  });
}

Future<void> outline(List<String> arguments, {Benchmarker? benchmarker}) async {
  return await runProtectedFromAbort<void>(() async {
    return await withGlobalOptions("outline", arguments, true, (
      CompilerContext c,
      _,
    ) async {
      if (c.options.verbose) {
        print("Building outlines for ${arguments.join(' ')}");
      }
      CompilerResult compilerResult = await generateKernelInternal(
        c,
        buildSummary: true,
        serializeIfBuildingSummary: false,
        buildComponent: false,
        benchmarker: benchmarker,
      );
      Component component = compilerResult.component!;
      await _emitComponent(
        c.options,
        component,
        benchmarker: benchmarker,
        message: "Wrote outline to ",
      );
    });
  });
}

Future<Uri> compile(List<String> arguments, {Benchmarker? benchmarker}) async {
  return await runProtectedFromAbort<Uri>(() async {
    return await withGlobalOptions("compile", arguments, true, (
      CompilerContext c,
      _,
    ) async {
      if (c.options.verbose) {
        print("Compiling directly to Kernel: ${arguments.join(' ')}");
      }
      CompilerResult compilerResult = await generateKernelInternal(
        c,
        benchmarker: benchmarker,
      );
      Component component = compilerResult.component!;
      Uri uri = await _emitComponent(
        c.options,
        component,
        benchmarker: benchmarker,
        message: "Wrote component to ",
      );
      _benchmarkAstVisitor(component, benchmarker);
      return uri;
    });
  });
}

Future<Uri?> deps(List<String> arguments) async {
  return await runProtectedFromAbort<Uri?>(() async {
    FileSystemDependencyTracker tracker = new FileSystemDependencyTracker();
    return await withGlobalOptions("deps", arguments, true, tracker: tracker, (
      CompilerContext c,
      _,
    ) async {
      if (c.options.verbose) {
        print("Computing deps: ${arguments.join(' ')}");
      }
      await generateKernelInternal(
        c,
        buildSummary: true,
        serializeIfBuildingSummary: false,
      );
      return await _emitDeps(tracker, c.options.output);
    });
  });
}

/// Writes the [component] to the URI specified in the compiler options.
Future<Uri> _emitComponent(
  ProcessedOptions options,
  Component component, {
  Benchmarker? benchmarker,
  required String message,
}) async {
  Uri uri = options.output!;
  if (options.omitPlatform) {
    benchmarker?.enterPhase(BenchmarkPhases.omitPlatform);
    component.computeCanonicalNames();
    Component userCode = new Component(
      nameRoot: component.root,
      uriToSource: new Map<Uri, Source>.from(component.uriToSource),
    );
    userCode.setMainMethodAndMode(component.mainMethodName, true);
    for (Library library in component.libraries) {
      if (!library.importUri.isScheme("dart")) {
        userCode.libraries.add(library);
      }
    }
    component = userCode;
  }
  if (uri.isScheme("file")) {
    benchmarker?.enterPhase(BenchmarkPhases.writeComponent);
    await writeComponentToFile(component, uri);
    options.ticker.logMs("${message}${uri.toFilePath()}");
  }
  return uri;
}

Future<Uri?> _emitDeps(
  FileSystemDependencyTracker tracker, [
  Uri? output,
]) async {
  Uri? dFile;
  if (output != null) {
    dFile = new File(new File.fromUri(output).path + ".d").uri;
    await writeDepsFile(output, dFile, tracker.dependencies);
  }
  return dFile;
}

/// Runs a visitor on [component] for benchmarking.
void _benchmarkAstVisitor(Component component, Benchmarker? benchmarker) {
  if (benchmarker != null) {
    // When benchmarking also do a recursive visit of the produced component
    // that does nothing other than visiting everything. Do this to produce
    // a reference point for comparing inference time and serialization time.
    benchmarker.enterPhase(BenchmarkPhases.benchmarkAstVisit);
    component.accept(new EmptyRecursiveVisitorForBenchmarking());
  }
  benchmarker?.enterPhase(BenchmarkPhases.unknown);
}

class EmptyRecursiveVisitorForBenchmarking extends RecursiveVisitor {}

Future<void> compilePlatform(List<String> arguments) async {
  FileSystemDependencyTracker tracker = new FileSystemDependencyTracker();
  await withGlobalOptions(
    "compile_platform",
    arguments,
    false,
    tracker: tracker,
    (CompilerContext c, List<String> restArguments) {
      c.compilingPlatform = true;
      Uri hostPlatform = Uri.base.resolveUri(new Uri.file(restArguments[2]));
      Uri outlineOutput = Uri.base.resolveUri(new Uri.file(restArguments[4]));
      return compilePlatformInternal(
        c,
        tracker,
        c.options.output!,
        outlineOutput,
        hostPlatform,
      );
    },
  );
}

Future<void> compilePlatformInternal(
  CompilerContext c,
  FileSystemDependencyTracker tracker,
  Uri fullOutput,
  Uri outlineOutput,
  Uri hostPlatform,
) async {
  if (c.options.verbose) {
    print("Generating outline of ${c.options.sdkRoot} into $outlineOutput");
    print("Compiling ${c.options.sdkRoot} to $fullOutput");
  }

  CompilerResult result = await generateKernelInternal(
    c,
    buildSummary: true,
    buildComponent: true,
  );
  new File.fromUri(outlineOutput).writeAsBytesSync(result.summary!);
  c.options.ticker.logMs("Wrote outline to ${outlineOutput.toFilePath()}");

  verifyComponent(
    c.options.target,
    VerificationStage.afterModularTransformations,
    result.component!,
  );
  await writeComponentToFile(result.component!, fullOutput);

  c.options.ticker.logMs("Wrote component to ${fullOutput.toFilePath()}");

  if (c.options.emitDeps) {
    List<Uri> deps = tracker.dependencies.toList();
    for (Uri dependency in await computeHostDependencies(hostPlatform)) {
      // Add the dependencies of the compiler's own sources.
      if (dependency != outlineOutput) {
        // We're computing the dependencies for [outlineOutput], so we shouldn't
        // include it in the deps file.
        deps.add(dependency);
      }
    }
    await writeDepsFile(
      fullOutput,
      new File(new File.fromUri(fullOutput).path + ".d").uri,
      deps,
    );
  }
}

Future<List<Uri>> computeHostDependencies(Uri hostPlatform) {
  // Do not try to parse compile_platform if it was precompiled into a binary.
  if (!Platform.script.toFilePath().endsWith('.dart')) {
    return Future.value([]);
  }

  // Returns a list of source files that make up the Fasta compiler (the files
  // the Dart VM reads to run Fasta). Until Fasta is self-hosting (in strong
  // mode), this is only an approximation, albeit accurate.  Once Fasta is
  // self-hosting, this isn't an approximation. Regardless, strong mode
  // shouldn't affect which files are read.
  Target? hostTarget = getTarget("vm", new TargetFlags());
  return getDependencies(
    Platform.script,
    platform: hostPlatform,
    target: hostTarget,
  );
}

Future<void> writeDepsFile(
  Uri output,
  Uri depsFile,
  List<Uri> allDependencies,
) async {
  if (allDependencies.isEmpty) return;
  String toRelativeFilePath(Uri uri) {
    // Ninja expects to find file names relative to the current working
    // directory. We've tried making them relative to the deps file, but that
    // doesn't work for downstream projects. Making them absolute also
    // doesn't work.
    //
    // We can test if it works by running ninja twice, for example:
    //
    //     ninja -C xcodebuild/ReleaseX64 -d explain compile_platform
    //     ninja -C xcodebuild/ReleaseX64 -d explain compile_platform
    //
    // The second time, ninja should say:
    //
    //     ninja: Entering directory `xcodebuild/ReleaseX64'
    //     ninja: no work to do.
    //
    // It's broken if it says something like this:
    //
    //     ninja explain: expected depfile 'vm_platform.dill.d' to mention \
    //     'vm_platform.dill', got '/.../xcodebuild/ReleaseX64/vm_platform.dill'
    return Uri.parse(relativizeUri(Uri.base, uri, isWindows)).toFilePath();
  }

  StringBuffer sb = new StringBuffer();
  sb.write(toRelativeFilePath(output));
  sb.write(":");
  List<String> paths = new List<String>.generate(
    allDependencies.length,
    (int i) => toRelativeFilePath(allDependencies[i]),
    growable: false,
  );
  // Sort the relative paths to ease analyzing future changes to this code.
  paths.sort();
  String? previous;
  for (String path in paths) {
    // Check for and omit duplicates.
    if (path != previous) {
      previous = path;
      sb.write(" \\\n  ");
      sb.write(path);
    }
  }
  sb.writeln();
  await new File.fromUri(depsFile).writeAsString("$sb");
}
