// Copyright (c) 2023, 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";

import "benchmarker.dart" as benchmarker;

const String compileDartRelativePath = "pkg/front_end/tool/compile.dart";

const int iterations = 3;

String? target;
String? changingWorkingDir;
String? sdkPath;
String? snapshotsPath;

void main(List<String> args) {
  if (args.contains("--help")) return _help();
  bool filter = false;
  bool raw = false;
  List<String> examines = [];
  List<String> extraVmArguments = [];
  for (String arg in args) {
    if (arg.startsWith("--target=")) {
      target = arg.substring("--target=".length);
    } else if (arg.startsWith("--changingWorkingDir=")) {
      changingWorkingDir = arg.substring("--changingWorkingDir=".length);
    } else if (arg.startsWith("--sdkPath=")) {
      sdkPath = arg.substring("--sdkPath=".length);
    } else if (arg.startsWith("--snapshotsPath=")) {
      snapshotsPath = arg.substring("--snapshotsPath=".length);
    } else if (arg == "--filter") {
      filter = true;
    } else if (arg == "--raw") {
      raw = true;
    } else if (arg.startsWith("--examine=")) {
      examines.addAll(arg.substring("--examine=".length).split(","));
    } else if (arg.startsWith("--extraVmArguments=")) {
      // E.g. "--old_gen_growth_rate=1000" in an attempt to even out GC stuff.
      extraVmArguments.add(arg.substring("--extraVmArguments=".length));
    } else {
      throw "Unknown argument: $arg";
    }
  }

  if (target == null) throw "Specify --target";
  if (changingWorkingDir == null) throw "Specify --changingWorkingDir";
  if (snapshotsPath == null) throw "Specify --snapshotsPath";
  if (sdkPath == null) throw "Specify --sdkPath";
  if (!new File("${sdkPath}bin/dart").existsSync()) {
    throw "--sdkPath doesn't contain bin/dart";
  }
  if (!new File("${sdkPath}bin/dartaotruntime").existsSync()) {
    throw "--sdkPath doesn't contain bin/dartaotruntime";
  }
  if (examines.isEmpty) {
    throw "Specify one or more commits to examine via --examine=";
  }

  for (String examine in examines) {
    if (examine.trim() == "") continue;
    _examine(examine, filter, raw, extraVmArguments);
  }
}

void _help() {
  print("CFE revision benchmarking tool");
  print("");
  print("Specify target, i.e. what we'll compile when benchmarking via");
  print("--target=<dart file>");
  print("Specify a git checkout that this script can manage");
  print("(and delete untracked files etc in) via");
  print("--changingWorkingDir=<checkout dir>");
  print("Specify the sdk to use via");
  print("--sdkPath=<path>");
  print("Specify where to save the snapshots via");
  print("--snapshotsPath=<path>");
  print("Specify which commit(s) to examine with");
  print("--examine=<revision>");
  print("(specify more either with more --examine= arguments,");
  print("or by comma-separation)");
  print("");
  print("Control output as needed with");
  print("--filter");
  print("and");
  print("--raw");
  print("");
  print("Specify extra arguments to pass to the VM with");
  print("--extraVmArguments=<whatever>");
  print("E.g. `--extraVmArguments=--old_gen_growth_rate=1000`");
  print("");
  print("Example run:");
  print("");
  print(r"out/ReleaseX64/dart-sdk/bin/dart \");
  print(r"  pkg/front_end/tool/compare_revisions_tool.dart \");
  print(r"  --target=pkg/front_end/tool/compile.dart \");
  print(r"  --changingWorkingDir=/tmp/tmp-playing-with-git/sdk/ \");
  print(r"  --sdkPath=67e9580b042/dart-sdk/ \");
  print(r"  --snapshotsPath=67e9580b042 \");
  print(r"  --examine=e7deece1fb2,529e016a0a7,fd02fec0fc4 \");
}

void _compileRevision(String gitCommit, {Stopwatch? stopwatch}) {
  if (new File("$snapshotsPath/platform.dill.$gitCommit").existsSync() &&
      new File("$snapshotsPath/compile.aot.$gitCommit").existsSync()) {
    return;
  }
  stopwatch ??= new Stopwatch()..start();

  // Clean up the git checkout.
  ProcessResult processResult = Process.runSync("git", [
    "reset",
    "--hard",
  ], workingDirectory: changingWorkingDir);
  if (processResult.exitCode != 0) {
    throw "Failed resetting hard for $gitCommit:\n"
        "stderr: ${processResult.stderr}\n"
        "stdout: ${processResult.stdout}";
  }
  processResult = Process.runSync("git", [
    "clean",
    "-d",
    "-f",
  ], workingDirectory: changingWorkingDir);
  if (processResult.exitCode != 0) {
    throw "Failed cleaning for $gitCommit:\n"
        "stderr: ${processResult.stderr}\n"
        "stdout: ${processResult.stdout}";
  }

  // Checkout at the specific revision.
  processResult = Process.runSync("git", [
    "checkout",
    gitCommit,
  ], workingDirectory: changingWorkingDir);
  if (processResult.exitCode != 0) {
    throw "Failed checking out $gitCommit:\n"
        "stderr: ${processResult.stderr}\n"
        "stdout: ${processResult.stdout}";
  }
  print(
    "Done running git checkout for $gitCommit after "
    "${stopwatch.elapsed.inSeconds} seconds.",
  );

  // Clean up the git checkout.
  processResult = Process.runSync("git", [
    "reset",
    "--hard",
  ], workingDirectory: changingWorkingDir);
  if (processResult.exitCode != 0) {
    throw "Failed resetting hard for $gitCommit:\n"
        "stderr: ${processResult.stderr}\n"
        "stdout: ${processResult.stdout}";
  }
  processResult = Process.runSync("git", [
    "clean",
    "-d",
    "-f",
  ], workingDirectory: changingWorkingDir);
  if (processResult.exitCode != 0) {
    throw "Failed cleaning for $gitCommit:\n"
        "stderr: ${processResult.stderr}\n"
        "stdout: ${processResult.stdout}";
  }

  // Run `gclient sync`.
  processResult = Process.runSync("gclient", [
    "sync",
    "-D",
  ], workingDirectory: changingWorkingDir);
  if (processResult.exitCode != 0) {
    throw "Failed gclient sync at $gitCommit:\n"
        "stderr: ${processResult.stderr}\n"
        "stdout: ${processResult.stdout}";
  }
  print(
    "Done running `gclient sync` for $gitCommit "
    "after ${stopwatch.elapsed.inSeconds} seconds.",
  );

  // Build the platform and copy it so we have it.
  processResult = Process.runSync("python3", [
    "tools/build.py",
    "-ax64",
    "-mrelease",
    "vm_platform",
  ], workingDirectory: changingWorkingDir);
  if (processResult.exitCode != 0) {
    throw "Failed compile vm platform at $gitCommit:\n"
        "stderr: ${processResult.stderr}\n"
        "stdout: ${processResult.stdout}";
  }
  new File(
    "$changingWorkingDir/out/ReleaseX64/vm_platform.dill",
  ).copySync("$snapshotsPath/platform.dill.$gitCommit");
  print(
    "Done building the platform for $gitCommit "
    "after ${stopwatch.elapsed.inSeconds} seconds.",
  );

  // Compile the AOT snapshot.
  processResult = Process.runSync("${sdkPath}bin/dart", [
    "compile",
    "aot-snapshot",
    "$changingWorkingDir/$compileDartRelativePath",
    "-o",
    "$snapshotsPath/compile.aot.$gitCommit",
  ]);
  if (processResult.exitCode != 0) {
    throw "Failed compile aot-snapshot at $gitCommit:\n"
        "stderr: ${processResult.stderr}\n"
        "stdout: ${processResult.stdout}";
  }
  print(
    "Compiled for $gitCommit "
    "after ${stopwatch.elapsed.inSeconds} seconds.",
  );
}

void _examine(
  String revision,
  bool filter,
  bool raw,
  List<String> extraVmArguments,
) {
  ProcessResult processResult = Process.runSync("git", [
    "log",
    "$revision^^...$revision",
    "--pretty=format:%h",
  ], workingDirectory: changingWorkingDir);
  if (processResult.exitCode != 0) {
    throw "Failed to get log:\n"
        "stderr: ${processResult.stderr}\n"
        "stdout: ${processResult.stdout}";
  }

  List<String> revisions = processResult.stdout.split("\n").reversed.toList();
  if (revisions.length != 2) throw "Expected 2 revisions but got $revisions";
  if (revisions.last != revision) {
    throw "Expected $revision but got ${revisions.last}";
  }
  String prevRevision = revisions.first;

  print("Creating AOT-snapshots if needed.");
  _compileRevision(prevRevision);
  _compileRevision(revision);

  print("Will now examine $prevRevision -> $revision.");

  print("Running with verbose GC.");
  benchmarker.GCInfo gcPrev = _runVerboseGc(prevRevision, extraVmArguments);
  benchmarker.GCInfo gcCurrent = _runVerboseGc(revision, extraVmArguments);
  benchmarker.printGcDiff(gcPrev, gcCurrent);

  print("Running $iterations iterations for $prevRevision.");
  List<Map<String, num>> benchmarkDataFrom = [];
  _run(iterations, prevRevision, extraVmArguments, benchmarkDataFrom);

  print("Running $iterations iterations for $revision.");
  List<Map<String, num>> benchmarkDataTo = [];
  _run(iterations, revision, extraVmArguments, benchmarkDataTo);

  if (filter) {
    // Filter to only "instructions:u".
    benchmarkDataFrom = _filterToInstructions(benchmarkDataFrom);
    benchmarkDataTo = _filterToInstructions(benchmarkDataTo);
  }
  if (raw) {
    print("From: $benchmarkDataFrom");
    print("To: $benchmarkDataTo");
  }

  print("Examine: $prevRevision -> $revision:");
  if (!benchmarker.compare(benchmarkDataFrom, benchmarkDataTo)) {
    print("No change.");
  }
}

void _run(
  int iterations,
  String gitCommit,
  List<String> extraVmArguments,
  List<Map<String, num>> output,
) {
  for (int i = 0; i < iterations; i++) {
    try {
      output.add(
        benchmarker.benchmark(
          "$snapshotsPath/compile.aot.$gitCommit",
          extraVmArguments,
          ["--platform=$snapshotsPath/platform.dill.$gitCommit", target!],
          aotRuntime: "${sdkPath}bin/dartaotruntime",
        ),
      );
    } catch (e) {
      throw "Failed to run benchmark at $gitCommit";
    }
  }
}

benchmarker.GCInfo _runVerboseGc(
  String gitCommit,
  List<String> extraVmArguments,
) {
  ProcessResult processResult =
      Process.runSync("${sdkPath}bin/dartaotruntime", [
        "--deterministic",
        "--verbose-gc",
        ...extraVmArguments,
        "$snapshotsPath/compile.aot.$gitCommit",
        "--platform=$snapshotsPath/platform.dill.$gitCommit",
        target!,
      ]);

  if (processResult.exitCode != 0) {
    throw "Run failed for $gitCommit with exit code "
        "${processResult.exitCode}.\n"
        "stdout:\n${processResult.stdout}\n\n"
        "stderr:\n${processResult.stderr}\n\n";
  }

  return benchmarker.parseVerboseGcOutput(processResult);
}

List<Map<String, num>> _filterToInstructions(
  List<Map<String, num>> input, {
  List<num>? extractedNumbers,
}) {
  List<Map<String, num>> result = [];
  for (Map<String, num> map in input) {
    num? instructionsValue = map["instructions:u"];
    if (instructionsValue != null) {
      result.add({"instructions:u": instructionsValue});
      extractedNumbers?.add(instructionsValue);
    }
  }
  return result;
}
