// Copyright (c) 2024, 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:async";
import "dart:convert";
import "dart:io";
import "dart:io" as io;
import "dart:math";

final buildDirs = [
  "out/ReleaseX64",
  "out/ReleaseX64C",
  "out/ReleaseSIMARM64",
  "out/ReleaseSIMARM64C",
  "out/ReleaseSIMRISCV64",
  "out/DebugX64",
  "out/DebugX64C",
  "out/DebugSIMARM64",
  "out/DebugSIMARM64C",
  "out/DebugSIMRISCV64",
];

final profilerFlags = [
  "--profile_vm=true", // default is different for simulators
  "--profile_vm=false",
  "--profile_period=${range(500, 10000)}",
  "--max_profile_depth=${range(8, 256)}",
  "--sample_buffer_duration=${range(30, 60)}",
];

final gcFlags = [
  "--compactor_tasks=${range(1, 3)}",
  "--dontneed_on_sweep",
  "--force_evacuation",
  "--mark_when_idle",
  "--marker_tasks=${range(1, 3)}",
  "--no_concurrent_mark",
  "--no_concurrent_sweep",
  "--no_inline_alloc",
  "--runtime_allocate_old",
  "--runtime_allocate_spill_tlab",
  "--scavenger_tasks=${range(1, 3)}",
  "--use_compactor",
  "--verify_after_gc",
  "--verify_after_marking",
  "--verify_before_gc",
  "--verify_store_buffer",
  "--write_protect_code",
  "--gc_at_throw",
];

final compilerFlags = [
  "--branch_coverage",
  "--code_comments",
  "--force_clone_compiler_objects",
  "--force_indirect_calls",
  "--force_switch_dispatch_type=${range(0, 2)}",
  "--inlining_callee_call_sites_threshold=${range(1, 3)}",
  "--inlining_callee_size_threshold=${range(100, 300)}",
  "--inlining_caller_size_threshold=${range(10000, 100000)}",
  "--inlining_depth_threshold=${range(2, 8)}",
  "--inlining_hotness=${range(5, 20)}",
  "--inlining_recursion_depth_threshold=${range(0, 3)}",
  "--inlining_size_threshold=${range(15, 35)}",
  "--inlining_small_leaf_size_threshold=${range(40, 60)}",
  "--link_natives_lazily",
  "--max_equality_polymorphic_checks=${range(8, 256)}",
  "--max_polymorphic_checks=${range(4, 12)}",
  "--no_array_bounds_check_elimination",
  "--no_background_compilation",
  "--no_compress_deopt_info",
  "--no_dead_store_elimination",
  "--no_enable_peephole",
  "--no_guess_icdata_cid",
  "--no_intrinsify",
  "--no_load_cse",
  "--no_polymorphic_with_deopt",
  "--no_propagate_ic_data",
  "--no_prune_dead_locals",
  "--no_remove_redundant_phis",
  "--no_reorder_basic_blocks",
  "--no_truncating_left_shift",
  "--no_two_args_smi_icd",
  "--no_unopt_megamorphic_calls",
  "--no_unopt_monomorphic_calls",
  "--no_use_cha_deopt",
  "--no_use_field_guards",
  "--no_use_osr",
  "--no_use_register_cc",
  "--optimization_counter_threshold=${range(1000, 50000)}",
  "--optimization_level=${range(1, 3)}",
  "--target_unknown_cpu",
  "--test_il_serialization",
  "--use_slow_path",
];

final random = new Random();
int range(int min, int max) {
  return random.nextInt(max - min + 1) + min;
}

String oneOf(List<String> choices) {
  return choices[random.nextInt(choices.length)];
}

List<String> someOf(List<String> choices) {
  var result = <String>[];
  for (var i = 0, n = range(0, 2); i < n; i++) {
    result.add(oneOf(choices));
  }
  return result;
}

List<String> someJitRuntimeFlags() {
  return [
    "--profiler", // Off by default unless VM service enabled
    ...someOf(profilerFlags),
    ...someOf(gcFlags),
    ...someOf(compilerFlags),
  ];
}

List<String> someAotRuntimeFlags() {
  return [
    "--profiler", // Off by default unless VM service enabled
    ...someOf(profilerFlags),
    ...someOf(gcFlags),
  ];
}

List<String> someGenSnapshotFlags() {
  return [...someOf(gcFlags), ...someOf(compilerFlags)];
}

Stopwatch stopwatch = new Stopwatch();

const overallTimeout = Duration(minutes: 45);
Duration get remainingTimeout => overallTimeout - stopwatch.elapsed;

// LUCI will kill recipe steps if they go 1200 seconds without any output.
const statusTimeout = Duration(minutes: 5);
int pendingTaskCount = 0;
late Timer pendingTimer;
taskStart() {
  if (pendingTaskCount++ == 0) {
    pendingTimer = new Timer.periodic(statusTimeout, (timer) {
      print(
        "$pendingTaskCount tasks still running after "
        "${stopwatch.elapsed.inMinutes} minutes",
      );
    });
  }
}

taskEnd() {
  if (--pendingTaskCount == 0) {
    pendingTimer.cancel();
  }
}

test(List<String> Function(String) createDartCommand, int taskIndex) async {
  taskStart();

  var dartCommand = createDartCommand("out/dartfuzz/$taskIndex.js");
  var dartScript = dartCommand[0];
  var dartArguments = dartCommand.getRange(1, dartCommand.length).toList();

  var buildDir = oneOf(buildDirs);
  var commands;
  if (random.nextBool()) {
    // JIT
    commands = [
      [
        "$buildDir/dart",
        ...someJitRuntimeFlags(),
        dartScript,
        ...dartArguments,
      ],
      ["diff", "out/dartfuzz/expected.js", "out/dartfuzz/$taskIndex.js"],
    ];
  } else {
    // AOT
    commands = [
      [
        "out/ReleaseX64/dart",
        "pkg/vm/bin/gen_kernel.dart",
        "--platform=$buildDir/vm_platform.dill",
        "--aot",
        "--output=out/dartfuzz/$taskIndex.dill",
        dartScript,
      ],
      [
        "$buildDir/gen_snapshot",
        ...someGenSnapshotFlags(),
        "--snapshot_kind=app-aot-elf",
        "--elf=out/dartfuzz/$taskIndex.elf",
        "out/dartfuzz/$taskIndex.dill",
      ],
      [
        "$buildDir/dartaotruntime",
        ...someAotRuntimeFlags(),
        "out/dartfuzz/$taskIndex.elf",
        ...dartArguments,
      ],
      ["diff", "out/dartfuzz/expected.js", "out/dartfuzz/$taskIndex.js"],
    ];
  }

  for (int commandIndex = 0; commandIndex < commands.length; commandIndex++) {
    var command = commands[commandIndex];
    var executable = command[0];
    var arguments = command.getRange(1, command.length).toList();
    var cmdline = command.join(' ');
    print("Start: $cmdline");
    var timeout = remainingTimeout;
    if (timeout.isNegative) {
      print("Timeout: $cmdline");
      break;
    }
    var process = await Process.start(executable, arguments);
    var timedOut = false;
    var timer = new Timer(timeout, () {
      timedOut = true;
      Process.killPid(process.pid);
    });
    var exitCode = await process.exitCode;
    timer.cancel();
    if (timedOut) {
      print("Timeout: $cmdline");
      break;
    } else if (exitCode == 0) {
      print("Success: $cmdline");
      process.stdout.drain();
      process.stderr.drain();
    } else {
      var stdout = await utf8.decodeStream(process.stdout);
      var stderr = await utf8.decodeStream(process.stderr);
      print("");
      print("=== FAILURE ===");
      for (int i = 0; i <= commandIndex; i++) {
        print("command: ${commands[i].join(' ')}");
      }
      print("exitCode: $exitCode");
      print("stdout:");
      print(stdout);
      print("stderr:");
      print(stderr);
      io.exitCode = 1;
      break;
    }
  }

  taskEnd();
}

shard(List<String> Function(String) createDartCommand, int shardIndex) async {
  while (!remainingTimeout.isNegative) {
    await test(createDartCommand, shardIndex);
  }
}

flagFuzz(List<String> Function(String) createDartCommand) async {
  stopwatch.start();

  await Directory("out/dartfuzz").create();

  var executable = "out/ReleaseX64/dart";
  var arguments = createDartCommand("out/dartfuzz/expected.js");
  var processResult = await Process.run(executable, arguments);
  if (processResult.exitCode != 0) {
    print("=== FAILURE ===");
    print("command: $executable ${arguments.join(' ')}");
    print("stdout:");
    print(processResult.stdout);
    print("stderr:");
    print(processResult.stderr);
    io.exitCode = 1;
    return;
  }

  for (var i = 0; i < Platform.numberOfProcessors; i++) {
    shard(createDartCommand, i);
  }
}
