// 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:async';

import 'coverage_helper.dart';
import 'vm_service_helper.dart' as vmService;

Future<void> main(List<String> args) async {
  CoverageHelper coverageHelper = new CoverageHelper();

  List<String> allArgs = <String>[];
  allArgs.addAll([
    "--disable-dart-dev",
    "--enable-asserts",
    "--pause_isolates_on_exit",
  ]);
  allArgs.addAll(args);

  await coverageHelper.start(allArgs);
}

class CoverageHelper extends vmService.LaunchingVMServiceHelper {
  final bool forceCompilation;
  final bool printHits;
  final bool doPrint;

  CoverageHelper({
    this.forceCompilation = false,
    this.printHits = true,
    this.doPrint = true,
  });

  @override
  Future<void> run() async {
    vmService.VM vm = await serviceClient.getVM();
    if (vm.isolates!.length != 1) {
      throw "Expected 1 isolate, got ${vm.isolates!.length}";
    }
    vmService.IsolateRef isolateRef = vm.isolates!.single;
    await waitUntilIsolateIsRunnable(isolateRef.id!);
    await serviceClient.resume(isolateRef.id!);
    Completer<String> cTimeout = new Completer();
    Timer timer = new Timer(new Duration(minutes: 20), () {
      cTimeout.complete("Timeout");
      killProcess();
    });

    Completer<String> cRunDone = new Completer();
    // ignore: unawaited_futures
    waitUntilPaused(isolateRef.id!).then((value) => cRunDone.complete("Done"));

    await Future.any([cRunDone.future, cTimeout.future, cProcessExited.future]);

    timer.cancel();

    if (!await isPausedAtExit(isolateRef.id!)) {
      killProcess();
      throw "Expected to be paused at exit, but is just paused!";
    }

    // Get and process coverage information.
    Stopwatch stopwatch = new Stopwatch()..start();
    vmService.SourceReport sourceReport = await serviceClient.getSourceReport(
      isolateRef.id!,
      [vmService.SourceReportKind.kCoverage],
      forceCompile: forceCompilation,
    );
    print("Got source report from VM in ${stopwatch.elapsedMilliseconds} ms");
    stopwatch.reset();
    Coverage coverage = getCoverageFromSourceReport([
      sourceReport,
    ], includeCoverageFor);

    // It's paused at exit, so resuming should allow us to exit.
    await serviceClient.resume(isolateRef.id!);

    if (doPrint) {
      coverage.printCoverage(printHits);
    }
    gotCoverage(coverage);
  }

  void gotCoverage(Coverage coverage) {}

  bool includeCoverageFor(Uri uri) {
    if (uri.isScheme("dart")) {
      return false;
    }
    if (uri.isScheme("package")) {
      return uri.pathSegments.first == "front_end" ||
          uri.pathSegments.first == "_fe_analyzer_shared" ||
          uri.pathSegments.first == "kernel";
    }
    return true;
  }

  Completer<String> cProcessExited = new Completer();
  @override
  void processExited(int exitCode) {
    cProcessExited.complete("Exit");
  }
}
