// Copyright (c) 2021, 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' show Future;
import 'dart:convert' show LineSplitter, utf8;
import 'dart:io' show File, Platform, Process, ProcessResult;

Future<void> main(List<String> args) async {
  // General idea: Launch - in separate processes - whatever we want to run
  // concurrently, capturing the stdout and stderr, printing it with some
  // prepended identification.
  // When all runs are done, fail if any fails.
  // Later we might be able to move it to the "testRunner"-system, if that
  // offers any advantages.

  print(
    "NOTE: This machine has ${Platform.numberOfProcessors} processors!"
    "\n\n",
  );

  List<WrappedProcess> startedProcesses = [];
  List<String> missingScripts = [];
  void noteMissingScript(String message) {
    missingScripts.add(message);
    print(message);
  }

  {
    // Very slow: Leak-test.
    Uri leakTester = Platform.script.resolve(
      "flutter_gallery_leak_tester.dart",
    );
    if (!new File.fromUri(leakTester).existsSync()) {
      noteMissingScript("Couldn't find $leakTester");
    } else {
      // The tools/bots/flutter/compile_flutter.sh script passes `--path`
      // --- we'll just pass everything along.
      startedProcesses.add(
        await run([leakTester.toString(), ...args], "leak test"),
      );
    }
  }

  {
    // Strong suite with fuzzing.
    Uri strongSuite = Platform.script.resolve("strong_suite.dart");
    if (!new File.fromUri(strongSuite).existsSync()) {
      noteMissingScript("Couldn't find $strongSuite");
    } else {
      startedProcesses.add(
        await run([strongSuite.toString(), "-DsemiFuzz=true"], "strong suite"),
      );
    }
  }

  {
    // Leak tests of incremental suite tests.
    Uri incrementalLeakTest = Platform.script.resolve(
      "vm_service_for_leak_detection.dart",
    );
    if (!new File.fromUri(incrementalLeakTest).existsSync()) {
      noteMissingScript("Couldn't find $incrementalLeakTest");
    } else {
      startedProcesses.add(
        await run([
          incrementalLeakTest.toString(),
          "--weekly",
        ], "incremental leak test"),
      );
    }
  }

  {
    // Expression suite with fuzzing.
    Uri expressionSuite = Platform.script.resolve("expression_suite.dart");
    if (!new File.fromUri(expressionSuite).existsSync()) {
      noteMissingScript("Couldn't find $expressionSuite");
    } else {
      startedProcesses.add(
        await run([
          expressionSuite.toString(),
          "-Dfuzz=true",
        ], "expression suite"),
      );
    }
  }

  // Wait for everything to finish.
  bool shouldThrow = false;
  List<int> exitCodes = await Future.wait(
    startedProcesses.map((e) => e.process.exitCode),
  );
  if (exitCodes.where((e) => e != 0).isNotEmpty) {
    shouldThrow = true;
    print("\n\nFound failures!:\n");
    // At least one failed.
    for (WrappedProcess p in startedProcesses) {
      int pExitCode = await p.process.exitCode;
      if (pExitCode != 0) {
        print("${p.id} failed with exist-code $pExitCode");
      }
    }
  }
  if (missingScripts.isNotEmpty) {
    print("\n\nThere were missing scripts!");
    for (String message in missingScripts) {
      print(" - $message");
    }
    shouldThrow = true;
  }

  // Now run all coverage and print a diff.
  WrappedProcess coverageProcess = await run([
    Platform.script.resolve("run_all_coverage_update.dart").toString(),
  ], "coverage update");
  await coverageProcess.process.exitCode;
  ProcessResult coverageDiffResult = Process.runSync("git", ["diff"]);
  print(coverageDiffResult.stdout);

  if (shouldThrow) throw "There were failures!";
}

Future<WrappedProcess> run(List<String> args, String id) async {
  Stopwatch stopwatch = new Stopwatch()..start();
  Process process = await Process.start(Platform.resolvedExecutable, [
    "--enable-asserts",
    ...args,
  ]);
  List<String> observatoryLines = [];
  process.stderr.transform(utf8.decoder).transform(new LineSplitter()).listen((
    line,
  ) {
    print("$id stderr> $line");
    if (line.contains("The Dart VM service is listening on")) {
      observatoryLines.add(line);
    }
  });
  process.stdout.transform(utf8.decoder).transform(new LineSplitter()).listen((
    line,
  ) {
    print("$id stdout> $line");
    if (line.contains("The Dart VM service is listening on")) {
      observatoryLines.add(line);
    }
  });
  // ignore: unawaited_futures
  process.exitCode.then((int exitCode) {
    stopwatch.stop();
    print(
      "$id finished in ${stopwatch.elapsed.toString()} "
      "with exit code $exitCode",
    );
  });
  return new WrappedProcess(process, id, observatoryLines);
}

class WrappedProcess {
  final Process process;
  final String id;
  final List<String> observatoryLines;

  WrappedProcess(this.process, this.id, this.observatoryLines);
}
