// Copyright (c) 2025, 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:io';

import 'package:testing/testing.dart'
    show
        Chain,
        ChainContext,
        Result,
        Step,
        TestDescription,
        ExpectationSet,
        Expectation;

import '../tool/coverage_merger.dart' as coverageMerger;
import 'coverage_helper.dart';
import 'testing/environment_keys.dart';
import 'testing_utils.dart' show checkEnvironment;
import 'utils/kernel_chain.dart';
import 'utils/suite_utils.dart';
import 'vm_service_coverage.dart';

void main([List<String> arguments = const []]) => internalMain(
  createContext,
  arguments: arguments,
  displayName: "coverage merger suite",
  configurationPath: "../testing.json",
);

const List<Map<String, String>> EXPECTATIONS = [
  {"name": "ExpectationFileMismatch", "group": "Fail"},
  {"name": "ExpectationFileMissing", "group": "Fail"},
];

Future<Context> createContext(Chain suite, Map<String, String> environment) {
  const Set<String> knownEnvironmentKeys = {EnvironmentKeys.updateExpectations};
  checkEnvironment(environment, knownEnvironmentKeys);

  return new Future.value(new Context(suite.name, environment));
}

class CheckCoverageData extends Step<TestDescription, void, Context> {
  const CheckCoverageData();

  @override
  String get name => "CheckCoverageData";

  @override
  Future<Result<void>> run(TestDescription description, Context context) async {
    Directory tmpDir = Directory.systemTemp.createTempSync(
      "coverage_merger_test",
    );
    try {
      Directory dartToolDir = new Directory.fromUri(
        tmpDir.uri.resolve(".dart_tool/"),
      );
      dartToolDir.createSync(recursive: true);
      File packageConfig = new File.fromUri(
        tmpDir.uri.resolve(".dart_tool/package_config.json"),
      );
      // We claim it being called 'front_end' as that's (currently at least) the
      // only package we process (almost) all files for.
      packageConfig.writeAsStringSync("""{
  "configVersion": 2,
  "packages": [
    {
      "name": "front_end",
      "rootUri": "../",
      "packageUri": "lib/",
      "languageVersion": "3.8"
    }
  ]
}""");
      Directory libDir = new Directory.fromUri(tmpDir.uri.resolve("lib/"));
      libDir.createSync(recursive: true);
      File main = new File.fromUri(tmpDir.uri.resolve("lib/main.dart"));
      File sourceFile = new File.fromUri(description.uri);
      main.writeAsStringSync(sourceFile.readAsStringSync().trim());

      CollectingCoverageHelper helper = new CollectingCoverageHelper();
      await helper.start(
        [
          "--disable-dart-dev",
          "--enable-asserts",
          "--pause_isolates_on_exit",
          main.path,
        ],
        stdoutReceiver: (String line) {
          print(" > $line");
        },
        stderrReceiver: (String line) {
          print("e> $line");
        },
      );
      Coverage coverage = await helper.completer.future;
      Directory coverageDir = new Directory.fromUri(
        tmpDir.uri.resolve("coverage/"),
      );
      coverageDir.createSync(recursive: true);
      File coverageFile = new File.fromUri(
        tmpDir.uri.resolve("coverage/coverage.json"),
      );
      coverage.writeToFile(coverageFile);

      Map<Uri, coverageMerger.CoverageInfo> coverageData = (await coverageMerger
          .mergeFromDirUri(
            packageConfig.uri,
            coverageDir.uri,
            silent: true,
            extraCoverageIgnores: ["coverage-ignore(suite):"],
            extraCoverageBlockIgnores: ["coverage-ignore-block(suite):"],
            addAndRemoveCommentsInFiles: false,
            stdoutReceiver: (String line) {
              print(" > $line");
            },
            stderrReceiver: (String line) {
              print("e> $line");
            },
          ))!;
      if (coverageData.values.first.error) {
        print("Warning: Got an error.");
      }

      Result<TestDescription> expectMatch = await context
          .match<TestDescription>(
            ".visualization.expect",
            coverageData.values.first.visualization.trim(),
            description.uri,
            description,
          );
      if (expectMatch.outcome != Expectation.pass) return expectMatch;

      coverageData = (await coverageMerger.mergeFromDirUri(
        packageConfig.uri,
        coverageDir.uri,
        silent: true,
        extraCoverageIgnores: ["coverage-ignore(suite):"],
        extraCoverageBlockIgnores: ["coverage-ignore-block(suite):"],
        addAndRemoveCommentsInFiles: true,
        stdoutReceiver: (String line) {
          print(" > $line");
        },
        stderrReceiver: (String line) {
          print("e> $line");
        },
      ))!;

      print("Reading ${main.path}");

      String outputWithComments = main.readAsStringSync().trim();
      return await context.match<TestDescription>(
        ".commented.expect",
        outputWithComments,
        description.uri,
        description,
      );
    } finally {
      try {
        tmpDir.deleteSync(recursive: true);
      } catch (e) {
        // Wait a little and retry.
        sleep(const Duration(milliseconds: 42));
        try {
          tmpDir.deleteSync(recursive: true);
        } catch (e) {
          print('Warning: $e');
        }
      }
    }
  }
}

class CollectingCoverageHelper extends CoverageHelper {
  Completer<Coverage> completer = new Completer();

  CollectingCoverageHelper() : super(doPrint: false, forceCompilation: true);

  @override
  void gotCoverage(Coverage coverage) {
    completer.complete(coverage);
  }
}

class Context extends ChainContext with MatchContext {
  final String suiteName;

  @override
  final List<Step> steps = const <Step>[const CheckCoverageData()];

  @override
  final bool updateExpectations;

  @override
  final ExpectationSet expectationSet = new ExpectationSet.fromJsonList(
    EXPECTATIONS,
  );

  Context(this.suiteName, Map<String, String> environment)
    : updateExpectations =
          environment[EnvironmentKeys.updateExpectations] == "true";

  @override
  bool get canBeFixWithUpdateExpectations => true;

  @override
  String get updateExpectationsOption =>
      '${EnvironmentKeys.updateExpectations}=true';
}
