// Copyright (c) 2019, 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 'annotated_code_helper.dart';
import 'id.dart';
import 'id_generation.dart';
import '../util/colors.dart' as colors;
import '../util/options.dart';

const String cfeMarker = 'cfe';
const String cfeWithNnbdMarker = '$cfeMarker:nnbd';
const String dart2jsMarker = 'dart2js';
const String analyzerMarker = 'analyzer';

/// Markers used in annotated tests shared by CFE, analyzer and dart2js.
const List<String> sharedMarkers = [
  cfeMarker,
  dart2jsMarker,
  analyzerMarker,
];

/// Markers used in annotated tests shared by CFE and analyzer.
const List<String> cfeAnalyzerMarkers = [
  cfeMarker,
  analyzerMarker,
];

/// Markers used in annotated tests shared by CFE, analyzer and dart2js.
const List<String> sharedMarkersWithNnbd = [
  cfeMarker,
  cfeWithNnbdMarker,
  dart2jsMarker,
  analyzerMarker,
];

/// Markers used in annotated tests used by CFE in both with and without nnbd.
const List<String> cfeMarkersWithNnbd = [
  cfeMarker,
  cfeWithNnbdMarker,
];

/// `true` if ANSI colors are supported by stdout.
bool useColors = stdout.supportsAnsiEscapes;

/// Colorize a message [text], if ANSI colors are supported.
String colorizeMessage(String text) {
  if (useColors) {
    return '${colors.YELLOW_COLOR}${text}${colors.DEFAULT_COLOR}';
  } else {
    return text;
  }
}

/// Colorize a matching annotation [text], if ANSI colors are supported.
String colorizeMatch(String text) {
  if (useColors) {
    return '${colors.BLUE_COLOR}${text}${colors.DEFAULT_COLOR}';
  } else {
    return text;
  }
}

/// Colorize a single annotation [text], if ANSI colors are supported.
String colorizeSingle(String text) {
  if (useColors) {
    return '${colors.GREEN_COLOR}${text}${colors.DEFAULT_COLOR}';
  } else {
    return text;
  }
}

/// Colorize the actual annotation [text], if ANSI colors are supported.
String colorizeActual(String text) {
  if (useColors) {
    return '${colors.RED_COLOR}${text}${colors.DEFAULT_COLOR}';
  } else {
    return text;
  }
}

/// Colorize an expected annotation [text], if ANSI colors are supported.
String colorizeExpected(String text) {
  if (useColors) {
    return '${colors.GREEN_COLOR}${text}${colors.DEFAULT_COLOR}';
  } else {
    return text;
  }
}

/// Colorize delimiter [text], if ANSI colors are supported.
String colorizeDelimiter(String text) {
  if (useColors) {
    return '${colors.YELLOW_COLOR}${text}${colors.DEFAULT_COLOR}';
  } else {
    return text;
  }
}

/// Colorize diffs [expected] and [actual] and [delimiter], if ANSI colors are
/// supported.
String colorizeDiff(String expected, String delimiter, String actual) {
  return '${colorizeExpected(expected)}'
      '${colorizeDelimiter(delimiter)}${colorizeActual(actual)}';
}

/// Colorize annotation delimiters [start] and [end] surrounding [text], if
/// ANSI colors are supported.
String colorizeAnnotation(String start, String text, String end) {
  return '${colorizeDelimiter(start)}$text${colorizeDelimiter(end)}';
}

/// Creates an annotation that shows the difference between [expected] and
/// [actual].
Annotation? createAnnotationsDiff(Annotation? expected, Annotation? actual) {
  if (identical(expected, actual)) return null;
  if (expected != null && actual != null) {
    return new Annotation(
        expected.index,
        expected.lineNo,
        expected.columnNo,
        expected.offset,
        expected.prefix,
        '${colorizeExpected(expected.text)}'
        '${colorizeDelimiter(' | ')}'
        '${colorizeActual(actual.text)}',
        expected.suffix);
  } else if (expected != null) {
    return new Annotation(
        expected.index,
        expected.lineNo,
        expected.columnNo,
        expected.offset,
        expected.prefix,
        '${colorizeExpected(expected.text)}'
        '${colorizeDelimiter(' | ')}'
        '${colorizeActual('---')}',
        expected.suffix);
  } else if (actual != null) {
    return new Annotation(
        actual.index,
        actual.lineNo,
        actual.columnNo,
        actual.offset,
        actual.prefix,
        '${colorizeExpected('---')}'
        '${colorizeDelimiter(' | ')}'
        '${colorizeActual(actual.text)}',
        actual.suffix);
  } else {
    return null;
  }
}

/// Encapsulates the member data computed for each source file of interest.
/// It's a glorified wrapper around a map of maps, but written this way to
/// provide a little more information about what it's doing. [DataType] refers
/// to the type this map is holding -- it is either [IdValue] or [ActualData].
class MemberAnnotations<DataType> {
  /// For each Uri, we create a map associating an element id with its
  /// corresponding annotations.
  final Map<Uri, Map<Id, DataType>> _computedDataForEachFile =
      new Map<Uri, Map<Id, DataType>>();

  /// Member or class annotations that don't refer to any of the user files.
  final Map<Id, DataType> globalData = <Id, DataType>{};

  void operator []=(Uri file, Map<Id, DataType> computedData) {
    _computedDataForEachFile[file] = computedData;
  }

  void forEach(void f(Uri file, Map<Id, DataType> computedData)) {
    _computedDataForEachFile.forEach(f);
  }

  Map<Id, DataType>? operator [](Uri file) {
    if (!_computedDataForEachFile.containsKey(file)) {
      _computedDataForEachFile[file] = <Id, DataType>{};
    }
    return _computedDataForEachFile[file];
  }

  @override
  String toString() {
    StringBuffer sb = new StringBuffer();
    sb.write('MemberAnnotations(');
    String comma = '';
    if (_computedDataForEachFile.isNotEmpty &&
        (_computedDataForEachFile.length > 1 ||
            _computedDataForEachFile.values.single.isNotEmpty)) {
      sb.write('data:{');
      _computedDataForEachFile.forEach((Uri uri, Map<Id, DataType> data) {
        sb.write(comma);
        sb.write('$uri:');
        sb.write(data);
        comma = ',';
      });
      sb.write('}');
    }
    if (globalData.isNotEmpty) {
      sb.write(comma);
      sb.write('global:');
      sb.write(globalData);
    }
    sb.write(')');
    return sb.toString();
  }
}

/// Compute a [MemberAnnotations] object from [code] for each marker in [maps]
/// specifying the expected annotations.
///
/// If an annotation starts with a marker, it is only expected for the
/// corresponding test configuration. Otherwise it is expected for all
/// configurations.
// TODO(johnniwinther): Support an empty marker set.
void computeExpectedMap(Uri sourceUri, String filename, AnnotatedCode code,
    Map<String, MemberAnnotations<IdValue>> maps,
    {required void onFailure(String message),
    bool preserveWhitespaceInAnnotations: false,
    bool preserveInfixWhitespaceInAnnotations: false}) {
  List<String> mapKeys = maps.keys.toList();
  Map<String, AnnotatedCode> split = splitByPrefixes(code, mapKeys);

  split.forEach((String marker, AnnotatedCode code) {
    MemberAnnotations<IdValue> fileAnnotations = maps[marker]!;
    // ignore: unnecessary_null_comparison
    assert(fileAnnotations != null, "No annotations for $marker in $maps");
    Map<Id, IdValue> expectedValues = fileAnnotations[sourceUri]!;
    for (Annotation annotation in code.annotations) {
      String text = annotation.text;
      IdValue idValue = IdValue.decode(sourceUri, annotation, text,
          preserveWhitespaceInAnnotations: preserveWhitespaceInAnnotations,
          preserveInfixWhitespace: preserveInfixWhitespaceInAnnotations);
      if (idValue.id.isGlobal) {
        if (fileAnnotations.globalData.containsKey(idValue.id)) {
          onFailure("Error in test '$filename': "
              "Duplicate annotations for ${idValue.id} in $marker: "
              "${idValue} and ${fileAnnotations.globalData[idValue.id]}.");
        }
        fileAnnotations.globalData[idValue.id] = idValue;
      } else {
        if (expectedValues.containsKey(idValue.id)) {
          onFailure("Error in test '$filename': "
              "Duplicate annotations for ${idValue.id} in $marker: "
              "${idValue} and ${expectedValues[idValue.id]}.");
        }
        expectedValues[idValue.id] = idValue;
      }
    }
  });
}

/// Creates a [TestData] object for the annotated test in [testFile].
///
/// If [testFile] is a file, use that directly. If it's a directory include
/// everything in that directory.
///
/// If [testLibDirectory] is not `null`, files in [testLibDirectory] with the
/// [testFile] name as a prefix are included.
TestData computeTestData(FileSystemEntity testFile,
    {required Iterable<String> supportedMarkers,
    required Uri createTestUri(Uri uri, String fileName),
    required void onFailure(String message),
    bool preserveWhitespaceInAnnotations: false,
    bool preserveInfixWhitespaceInAnnotations: false}) {
  Uri? entryPoint;

  String testName;
  File? mainTestFile;
  Uri testFileUri = testFile.uri;
  Map<String, File>? additionalFiles;
  if (testFile is File) {
    testName = testFileUri.pathSegments.last;
    mainTestFile = testFile;
    entryPoint = createTestUri(mainTestFile.uri, 'main.dart');
  } else if (testFile is Directory) {
    testName = testFileUri.pathSegments[testFileUri.pathSegments.length - 2];
    additionalFiles = new Map<String, File>();
    for (FileSystemEntity entry in testFile
        .listSync(recursive: true)
        .where((entity) => !entity.path.endsWith('~'))) {
      if (entry is! File) continue;
      if (entry.uri.pathSegments.last == "main.dart") {
        mainTestFile = entry;
        entryPoint = createTestUri(mainTestFile.uri, 'main.dart');
      } else {
        additionalFiles[entry.uri.path.substring(testFile.uri.path.length)] =
            entry;
      }
    }
    assert(
        mainTestFile != null, "No 'main.dart' test file found for $testFile.");
  } else {
    throw new UnimplementedError();
  }

  String annotatedCode = new File.fromUri(mainTestFile!.uri).readAsStringSync();
  Map<Uri, AnnotatedCode> code = {
    entryPoint!:
        new AnnotatedCode.fromText(annotatedCode, commentStart, commentEnd)
  };
  Map<String, MemberAnnotations<IdValue>> expectedMaps = {};
  for (String testMarker in supportedMarkers) {
    expectedMaps[testMarker] = new MemberAnnotations<IdValue>();
  }
  computeExpectedMap(entryPoint, testFile.uri.pathSegments.last,
      code[entryPoint]!, expectedMaps,
      onFailure: onFailure,
      preserveWhitespaceInAnnotations: preserveWhitespaceInAnnotations,
      preserveInfixWhitespaceInAnnotations:
          preserveInfixWhitespaceInAnnotations);
  Map<String, String> memorySourceFiles = {
    entryPoint.path: code[entryPoint]!.sourceCode
  };

  if (additionalFiles != null) {
    for (MapEntry<String, File> additionalFileData in additionalFiles.entries) {
      String libFileName = additionalFileData.key;
      File libEntity = additionalFileData.value;
      Uri libFileUri = createTestUri(libEntity.uri, libFileName);
      String libCode = libEntity.readAsStringSync();
      AnnotatedCode annotatedLibCode =
          new AnnotatedCode.fromText(libCode, commentStart, commentEnd);
      memorySourceFiles[libFileUri.path] = annotatedLibCode.sourceCode;
      code[libFileUri] = annotatedLibCode;
      computeExpectedMap(
          libFileUri, libFileName, annotatedLibCode, expectedMaps,
          onFailure: onFailure,
          preserveWhitespaceInAnnotations: preserveWhitespaceInAnnotations,
          preserveInfixWhitespaceInAnnotations:
              preserveInfixWhitespaceInAnnotations);
    }
  }

  return new TestData(
      testName, testFileUri, entryPoint, memorySourceFiles, code, expectedMaps);
}

/// Data for an annotated test.
class TestData {
  final String name;
  final Uri testFileUri;
  final Uri entryPoint;
  final Map<String, String> memorySourceFiles;
  final Map<Uri, AnnotatedCode> code;
  final Map<String, MemberAnnotations<IdValue>> expectedMaps;

  TestData(this.name, this.testFileUri, this.entryPoint, this.memorySourceFiles,
      this.code, this.expectedMaps);
}

/// The results for running a test on a single configuration.
class TestResult<T> {
  /// `true` if the [compiledData]  didn't match the expected annotations.
  final bool hasMismatches;

  /// `true` if the test couldn't be run due to errors in the test setup.
  final bool isErroneous;

  /// The data interpreter used to verify the [compiledData].
  final DataInterpreter<T>? interpreter;

  /// The actual data computed for the test.
  final CompiledData<T>? compiledData;

  TestResult(this.interpreter, this.compiledData, this.hasMismatches)
      : isErroneous = false;

  TestResult.erroneous()
      : isErroneous = true,
        hasMismatches = false,
        interpreter = null,
        compiledData = null;

  bool get hasFailures => hasMismatches || isErroneous;
}

/// The actual result computed for an annotated test.
abstract class CompiledData<T> {
  final Uri mainUri;

  /// For each Uri, a map associating an element id with the instrumentation
  /// data we've collected for it.
  final Map<Uri, Map<Id, ActualData<T>>> actualMaps;

  /// Collected instrumentation data that doesn't refer to any of the user
  /// files.  (E.g. information the test has collected about files in
  /// `dart:core`).
  final Map<Id, ActualData<T>> globalData;

  CompiledData(this.mainUri, this.actualMaps, this.globalData);

  Map<int, List<String>> computeAnnotations(Uri uri) {
    Map<Id, ActualData<T>> actualMap = actualMaps[uri]!;
    Map<int, List<String>> annotations = <int, List<String>>{};
    actualMap.forEach((Id id, ActualData<T> data) {
      String value1 = '${data.value}';
      annotations
          .putIfAbsent(data.offset, () => [])
          .add(colorizeActual(value1));
    });
    return annotations;
  }

  Map<int, List<String>> computeDiffAnnotationsAgainst(
      Map<Id, ActualData<T>> thisMap, Map<Id, ActualData<T>> otherMap, Uri uri,
      {bool includeMatches: false}) {
    Map<int, List<String>> annotations = <int, List<String>>{};
    thisMap.forEach((Id id, ActualData<T> thisData) {
      ActualData<T>? otherData = otherMap[id];
      String thisValue = '${thisData.value}';
      if (thisData.value != otherData?.value) {
        String otherValue = '${otherData?.value ?? '---'}';
        annotations
            .putIfAbsent(thisData.offset, () => [])
            .add(colorizeDiff(thisValue, ' | ', otherValue));
      } else if (includeMatches) {
        annotations
            .putIfAbsent(thisData.offset, () => [])
            .add(colorizeMatch(thisValue));
      }
    });
    otherMap.forEach((Id id, ActualData<T> otherData) {
      if (!thisMap.containsKey(id)) {
        String thisValue = '---';
        String otherValue = '${otherData.value}';
        annotations
            .putIfAbsent(otherData.offset, () => [])
            .add(colorizeDiff(thisValue, ' | ', otherValue));
      }
    });
    return annotations;
  }

  int getOffsetFromId(Id id, Uri uri);

  void reportError(Uri uri, int offset, String message, {bool succinct: false});
}

/// Interface used for interpreting annotations.
abstract class DataInterpreter<T> {
  /// Returns `null` if [actualData] satisfies the [expectedData] annotation.
  /// Otherwise, a message is returned contain the information about the
  /// problems found.
  String? isAsExpected(T actualData, String? expectedData);

  /// Returns `true` if [actualData] corresponds to empty data.
  bool isEmpty(T actualData);

  /// Returns a textual representation of [actualData].
  ///
  /// If [indentation] is provided a multiline pretty printing can be returned
  /// using [indentation] for additional lines.
  String getText(T actualData, [String? indentation]);
}

/// Default data interpreter for string data.
class StringDataInterpreter implements DataInterpreter<String> {
  const StringDataInterpreter();

  @override
  String? isAsExpected(String actualData, String? expectedData) {
    expectedData ??= '';
    if (actualData != expectedData) {
      return "Expected $expectedData, found $actualData";
    }
    return null;
  }

  @override
  bool isEmpty(String actualData) {
    return actualData == '';
  }

  @override
  String getText(String actualData, [String? indentation]) {
    return actualData;
  }
}

String withAnnotations(String sourceCode, Map<int, List<String>> annotations) {
  StringBuffer sb = new StringBuffer();
  int end = 0;
  for (int offset in annotations.keys.toList()..sort()) {
    if (offset >= sourceCode.length) {
      sb.write('...');
      return sb.toString();
    }
    if (offset > end) {
      sb.write(sourceCode.substring(end, offset));
    }
    for (String annotation in annotations[offset]!) {
      sb.write(colorizeAnnotation('/*', annotation, '*/'));
    }
    end = offset;
  }
  if (end < sourceCode.length) {
    sb.write(sourceCode.substring(end));
  }
  return sb.toString();
}

/// Checks [compiledData] against the expected data in [expectedMaps] derived
/// from [code].
Future<TestResult<T>> checkCode<T>(
    MarkerOptions markerOptions,
    String marker,
    String modeName,
    TestData testData,
    MemberAnnotations<IdValue> expectedMaps,
    CompiledData<T> compiledData,
    DataInterpreter<T> dataInterpreter,
    {bool filterActualData(IdValue? expected, ActualData<T> actualData)?,
    bool fatalErrors: true,
    bool succinct: false,
    required void onFailure(String message)}) async {
  String testName = testData.name;
  Map<Uri, AnnotatedCode> code = testData.code;

  bool hasFailure = false;
  Set<Uri> neededDiffs = new Set<Uri>();

  void checkActualMap(Map<Id, ActualData<T>> actualMap,
      Map<Id, IdValue>? expectedMap, Uri uri) {
    expectedMap ??= {};
    bool hasLocalFailure = false;
    actualMap.forEach((Id id, ActualData<T> actualData) {
      T actual = actualData.value;
      String actualText = dataInterpreter.getText(actual);

      if (!expectedMap!.containsKey(id)) {
        if (!dataInterpreter.isEmpty(actual)) {
          String actualValueText = IdValue.idToString(id, actualText);
          compiledData.reportError(
              actualData.uri,
              actualData.offset,
              succinct
                  ? 'EXTRA $modeName DATA for ${id.descriptor}'
                  : 'EXTRA $modeName DATA for ${id.descriptor}:\n '
                      'object   : ${actualData.objectText}\n '
                      'actual   : ${colorizeActual(actualValueText)}\n '
                      'Data was expected for these ids: ${expectedMap.keys}',
              succinct: succinct);
          if (filterActualData == null || filterActualData(null, actualData)) {
            hasLocalFailure = true;
          }
        }
      } else {
        IdValue expected = expectedMap[id]!;
        String? unexpectedMessage =
            dataInterpreter.isAsExpected(actual, expected.value);
        if (unexpectedMessage != null) {
          String actualValueText = IdValue.idToString(id, actualText);
          compiledData.reportError(
              actualData.uri,
              actualData.offset,
              succinct
                  ? 'UNEXPECTED $modeName DATA for ${id.descriptor}'
                  : 'UNEXPECTED $modeName DATA for ${id.descriptor}:\n '
                      'detail  : ${colorizeMessage(unexpectedMessage)}\n '
                      'object  : ${actualData.objectText}\n '
                      'expected: ${colorizeExpected('$expected')}\n '
                      'actual  : ${colorizeActual(actualValueText)}',
              succinct: succinct);
          if (filterActualData == null ||
              filterActualData(expected, actualData)) {
            hasLocalFailure = true;
          }
        }
      }
    });
    if (hasLocalFailure) {
      hasFailure = true;
      neededDiffs.add(uri);
    }
  }

  compiledData.actualMaps.forEach((Uri uri, Map<Id, ActualData<T>> actualMap) {
    checkActualMap(actualMap, expectedMaps[uri], uri);
  });
  checkActualMap(compiledData.globalData, expectedMaps.globalData,
      Uri.parse("global:data"));

  Set<Id> missingIds = new Set<Id>();
  void checkMissing(
      Map<Id, IdValue>? expectedMap, Map<Id, ActualData<T>>? actualMap,
      [Uri? uri]) {
    actualMap ??= {};
    expectedMap?.forEach((Id id, IdValue expected) {
      if (!actualMap!.containsKey(id)) {
        missingIds.add(id);
        String message = 'MISSING $modeName DATA for ${id.descriptor}: '
            'Expected ${colorizeExpected('$expected')}';
        if (uri != null) {
          compiledData.reportError(
              uri, compiledData.getOffsetFromId(id, uri), message,
              succinct: succinct);
        } else {
          print(message);
        }
      }
    });
    if (missingIds.isNotEmpty && uri != null) {
      neededDiffs.add(uri);
    }
  }

  expectedMaps.forEach((Uri uri, Map<Id, IdValue> expectedMap) {
    checkMissing(expectedMap, compiledData.actualMaps[uri], uri);
  });
  checkMissing(expectedMaps.globalData, compiledData.globalData);
  if (!succinct) {
    if (neededDiffs.isNotEmpty) {
      Map<Uri, List<Annotation>> annotations = computeAnnotationsPerUri(
          code,
          {'dummyMarker': expectedMaps},
          compiledData.mainUri,
          {'dummyMarker': compiledData.actualMaps},
          dataInterpreter,
          createDiff: createAnnotationsDiff);
      for (Uri uri in neededDiffs) {
        print('--annotations diff [${uri.pathSegments.last}]-------------');
        AnnotatedCode? annotatedCode = code[uri];
        print(new AnnotatedCode(annotatedCode?.annotatedCode ?? "",
                annotatedCode?.sourceCode ?? "", annotations[uri] ?? const [])
            .toText());
        print('----------------------------------------------------------');
      }
    }
  }
  if (missingIds.isNotEmpty) {
    print("MISSING ids: ${missingIds}.");
    hasFailure = true;
  }
  if (hasFailure && fatalErrors) {
    onFailure(generateErrorMessage(
      markerOptions,
      mismatches: {
        testName: {marker}
      },
    ));
  }
  return new TestResult<T>(dataInterpreter, compiledData, hasFailure);
}

typedef Future<Map<String, TestResult<T>>> RunTestFunction<T>(
    MarkerOptions markerOptions, TestData testData,
    {required bool testAfterFailures,
    required bool verbose,
    required bool succinct,
    required bool printCode,
    Map<String, List<String>>? skipMap,
    required Uri nullUri});

/// Compute the file: URI of the file located at `path`, where `path` is
/// relative to the root of the SDK repository.
///
/// We find the root of the SDK repository by looking for the parent of the
/// directory named `pkg`.
Uri _fileUriFromSdkRoot(String path) {
  Uri uri = Platform.script;
  List<String> pathSegments = uri.pathSegments;
  return uri.replace(pathSegments: [
    ...pathSegments.sublist(0, pathSegments.lastIndexOf('pkg')),
    ...path.split('/')
  ]);
}

/// Description of a tester for a specific marker.
///
/// A tester is the runnable dart script used to run the tests for a certain
/// configurations. For instance
/// `pkg/front_end/test/id_tests/constant_test.dart` is used to run the test
/// data in `pkg/_fe_analyzer_shared/test/constants/data/` using the front end
/// and `pkg/analyzer/test/id_tests/constant_test.dart` is used to run the same
/// test data using the analyzer.
class MarkerTester {
  /// The marker supported by this tester, for instance 'cfe' for front end
  /// testing.
  final String marker;

  /// The path of the tester relative to the sdk repo root, for instance
  /// `pkg/front_end/test/id_tests/constant_test.dart`.
  final String path;

  /// The resolved file uri for the test.
  final Uri uri;

  MarkerTester(this.marker, this.path, this.uri);

  @override
  String toString() => 'MarkerTester($marker,$path,$uri)';
}

/// A model of the testers defined in a `marker.options` file, located in the
/// data folder for id tests.
class MarkerOptions {
  /// The supported markers and their corresponding testers.
  final Map<String, MarkerTester> markers;

  MarkerOptions.internal(this.markers);

  factory MarkerOptions.fromDataDir(Directory dataDir,
      {bool shouldFindScript: true}) {
    File file = new File.fromUri(dataDir.uri.resolve('marker.options'));
    File script = new File.fromUri(Platform.script);
    if (!file.existsSync()) {
      throw new ArgumentError("Marker option file '$file' doesn't exist.");
    }

    Map<String, MarkerTester> markers = {};
    String text = file.readAsStringSync();
    bool isScriptFound = false;
    for (String line in text.split('\n')) {
      line = line.trim();
      if (line.isEmpty || line.startsWith('#')) continue;
      int eqPos = line.indexOf('=');
      if (eqPos == -1) {
        throw new ArgumentError(
            "Unsupported marker option '$line' in ${file.uri}");
      }
      String marker = line.substring(0, eqPos);
      String tester = line.substring(eqPos + 1);
      File testerFile = new File.fromUri(_fileUriFromSdkRoot(tester));
      if (!testerFile.existsSync()) {
        throw new ArgumentError(
            "Tester '$tester' does not exist for marker '$marker' in "
            "${file.uri}");
      }
      if (markers.containsKey(marker)) {
        throw new ArgumentError("Duplicate marker '$marker' in ${file.uri}");
      }
      markers[marker] = new MarkerTester(marker, tester, testerFile.uri);
      if (testerFile.absolute.uri == script.absolute.uri) {
        isScriptFound = true;
      }
    }
    if (shouldFindScript && !isScriptFound) {
      throw new ArgumentError(
          "Script '${script.uri}' not found in ${file.uri}");
    }
    return new MarkerOptions.internal(markers);
  }

  Iterable<String> get supportedMarkers => markers.keys;

  Future<void> runAll(List<String> args) async {
    Set<MarkerTester> testers = markers.values.toSet();
    bool allOk = true;
    for (MarkerTester tester in testers) {
      print('================================================================');
      print('Running tester: ${tester.path} ${args.join(' ')}');
      print('================================================================');
      Process process = await Process.start(
          Platform.resolvedExecutable, [tester.uri.toString(), ...args],
          mode: ProcessStartMode.inheritStdio);
      if (await process.exitCode != 0) {
        allOk = false;
      }
    }
    if (!allOk) {
      throw "Error(s) occurred.";
    }
  }
}

String getTestName(FileSystemEntity entity) {
  if (entity is Directory) {
    return entity.uri.pathSegments[entity.uri.pathSegments.length - 2];
  } else {
    return entity.uri.pathSegments.last;
  }
}

// TODO(johnniwinther): Support --show to show actual data for an input.
class Options {
  static const Option<bool> runAll =
      const Option<bool>('--run-all', const BoolValue(false));
  static const Option<bool> verbose =
      const Option<bool>('--verbose', const BoolValue(false), aliases: ['-v']);
  static const Option<bool> succinct =
      const Option<bool>('--succinct', const BoolValue(false), aliases: ['-s']);
  static const Option<bool> shouldContinue =
      const Option<bool>('--continue', const BoolValue(false), aliases: ['-c']);
  static const Option<bool> stopAfterFailures = const Option<bool>(
      '--stop-after-failures', const BoolValue(false),
      aliases: ['-a']);
  static const Option<bool> printCode = const Option<bool>(
      '--print-code', const BoolValue(false),
      aliases: ['-p']);
  static const Option<bool> generateAnnotations =
      const Option<bool>('--generate', const BoolValue(false), aliases: ['-g']);
  static const Option<bool> forceUpdate = const Option<bool>(
      '--force-update', const BoolValue(false),
      aliases: ['-f']);
}

const List<Option> idTestOptions = [
  Options.runAll,
  Options.verbose,
  Options.succinct,
  Options.shouldContinue,
  Options.stopAfterFailures,
  Options.printCode,
  Options.generateAnnotations,
  Options.forceUpdate,
];

/// Check code for all tests in [dataDir] using [runTest].
Future<void> runTests<T>(Directory dataDir,
    {List<String> args: const <String>[],
    int shards: 1,
    int shardIndex: 0,
    void onTest(Uri uri)?,
    required Uri createUriForFileName(String fileName),
    required void onFailure(String message),
    required RunTestFunction<T> runTest,
    List<String>? skipList,
    Map<String, List<String>>? skipMap,
    bool preserveWhitespaceInAnnotations: false,
    bool preserveInfixWhitespaceInAnnotations: false}) async {
  ParsedOptions parsedOptions = ParsedOptions.parse(args, idTestOptions);
  MarkerOptions markerOptions =
      new MarkerOptions.fromDataDir(dataDir, shouldFindScript: shards == 1);
  if (Options.runAll.read(parsedOptions)) {
    await markerOptions.runAll(Options.runAll.remove(args.toList()));
    return;
  }
  bool verbose = Options.verbose.read(parsedOptions);
  bool succinct = Options.succinct.read(parsedOptions);
  bool shouldContinue = Options.shouldContinue.read(parsedOptions);
  bool stopAfterFailures = Options.stopAfterFailures.read(parsedOptions);
  bool printCode = Options.printCode.read(parsedOptions);
  bool generateAnnotations = Options.generateAnnotations.read(parsedOptions);
  bool forceUpdate = Options.forceUpdate.read(parsedOptions);
  List<String> arguments = parsedOptions.arguments;

  bool continued = false;

  Map<String, Set<String>> mismatches = {};
  Map<String, Set<String>> errors = {};

  String relativeDir = dataDir.uri.path.replaceAll(Uri.base.path, '');
  print('Data dir: ${relativeDir}');
  List<FileSystemEntity> entities = dataDir
      .listSync()
      .where((entity) =>
          !entity.path.endsWith('~') &&
          !entity.path.endsWith('marker.options') &&
          !entity.path.endsWith('.expect'))
      .toList();
  if (shards > 1) {
    entities.sort((a, b) => getTestName(a).compareTo(getTestName(b)));
    int start = entities.length * shardIndex ~/ shards;
    int end = entities.length * (shardIndex + 1) ~/ shards;
    entities = entities.sublist(start, end);
  }
  int testCount = 0;
  for (FileSystemEntity entity in entities) {
    String testName = getTestName(entity);
    if (arguments.isNotEmpty && !arguments.contains(testName) && !continued) {
      continue;
    }
    if (shouldContinue) continued = true;
    testCount++;

    if (skipList != null &&
        skipList.contains(testName) &&
        !arguments.contains(testName)) {
      print('Skip: ${testName}');
      continue;
    }
    if (onTest != null) {
      onTest(entity.uri);
    }
    print('----------------------------------------------------------------');

    Map<Uri, Uri> testToFileUri = {};

    Uri createTestUri(Uri fileUri, String fileName) {
      Uri testUri = createUriForFileName(fileName);
      testToFileUri[testUri] = fileUri;
      return testUri;
    }

    TestData testData = computeTestData(entity,
        supportedMarkers: markerOptions.supportedMarkers,
        createTestUri: createTestUri,
        onFailure: onFailure,
        preserveWhitespaceInAnnotations: preserveWhitespaceInAnnotations,
        preserveInfixWhitespaceInAnnotations:
            preserveInfixWhitespaceInAnnotations);
    print('Test: ${testData.testFileUri}');

    Map<String, TestResult<T>> results = await runTest(markerOptions, testData,
        testAfterFailures: !stopAfterFailures || generateAnnotations,
        verbose: verbose,
        succinct: succinct,
        printCode: printCode,
        skipMap: skipMap,
        nullUri: createTestUri(entity.uri.resolve("null"), "null"));

    Set<String> mismatchMarkers = {};
    Set<String> errorMarkers = {};
    results.forEach((String marker, TestResult<T> result) {
      if (result.hasMismatches) {
        mismatchMarkers.add(marker);
      } else if (result.isErroneous) {
        errorMarkers.add(marker);
      }
    });
    if (errorMarkers.isNotEmpty) {
      // Cannot generate annotations for erroneous tests.
      if (mismatchMarkers.isNotEmpty) {
        mismatches[testName] = mismatchMarkers;
      }
      errors[testName] = errorMarkers;
    } else if (mismatchMarkers.isNotEmpty ||
        (forceUpdate && generateAnnotations)) {
      if (generateAnnotations) {
        DataInterpreter? dataInterpreter;
        Map<String, Map<Uri, Map<Id, ActualData<T>>>> actualData = {};
        results.forEach((String marker, TestResult<T> result) {
          dataInterpreter ??= result.interpreter;
          Map<Uri, Map<Id, ActualData<T>>> actualDataPerUri =
              actualData[marker] = {};

          void addActualData(Uri uri, Map<Id, ActualData<T>> actualData) {
            assert(
                // ignore: unnecessary_null_comparison
                uri != null && testData.code.containsKey(uri) ||
                    actualData.isEmpty,
                "Unexpected data ${actualData} for $uri");
            // ignore: unnecessary_null_comparison
            if (uri == null || actualData.isEmpty) {
              // TODO(johnniwinther): Avoid collecting data without
              //  invalid uris.
              return;
            }
            Map<Id, ActualData<T>> actualDataPerId =
                actualDataPerUri[uri] ??= {};
            actualDataPerId.addAll(actualData);
          }

          result.compiledData!.actualMaps.forEach(addActualData);
          addActualData(
              result.compiledData!.mainUri, result.compiledData!.globalData);
        });

        Map<Uri, List<Annotation>> annotations = computeAnnotationsPerUri(
            testData.code,
            testData.expectedMaps,
            testData.entryPoint,
            actualData,
            dataInterpreter!,
            forceUpdate: forceUpdate);
        annotations.forEach((Uri uri, List<Annotation> annotations) {
          // ignore: unnecessary_null_comparison
          assert(uri != null, "Annotations without uri: $annotations");
          AnnotatedCode? code = testData.code[uri];
          assert(code != null,
              "No annotated code for $uri with annotations: $annotations");
          AnnotatedCode generated = new AnnotatedCode(
              code?.annotatedCode ?? "", code?.sourceCode ?? "", annotations);
          Uri fileUri = testToFileUri[uri]!;
          new File.fromUri(fileUri).writeAsStringSync(generated.toText());
          print('Generated annotations for ${fileUri}');
        });
      } else {
        mismatches[testName] = mismatchMarkers;
      }
    }
  }
  if (mismatches.isNotEmpty || errors.isNotEmpty) {
    onFailure(generateErrorMessage(markerOptions,
        mismatches: mismatches, errors: errors));
  }
  if (testCount == 0) {
    onFailure("No files were tested.");
  }
}

/// Generates an error message for the [mismatches] and [errors] using
/// [markerOptions] to provide a re-run/re-generation command.
///
/// [mismatches] and [errors] are maps from the test names of the failing tests
/// to the markers for the configurations in which they failed.
String generateErrorMessage(MarkerOptions markerOptions,
    {Map<String, Set<String>> mismatches = const {},
    Map<String, Set<String>> errors = const {}}) {
  Set<String> testNames = {...mismatches.keys, ...errors.keys};
  StringBuffer message = new StringBuffer();
  message.writeln();
  message.writeln('==========================================================');
  message.writeln();
  if (testNames.length > 1) {
    message.writeln("Errors found in tests:");
    message.writeln();
    for (String testName in testNames.toList()..sort()) {
      message.writeln("  ${testName}");
    }
  } else {
    message.writeln("Errors found in test '${testNames.single}'");
  }
  if (mismatches.isNotEmpty) {
    Map<MarkerTester, Set<String>> regenerations = {};
    mismatches.forEach((String testName, Set<String> markers) {
      for (String marker in markers) {
        MarkerTester tester = markerOptions.markers[marker]!;
        (regenerations[tester] ??= {}).add(testName);
      }
    });
    message.writeln();
    if (regenerations.length > 1) {
      message.writeln('Run these commands to generate new expectations:');
    } else {
      message.writeln('Run this command to generate new expectations:');
    }
    message.writeln();
    regenerations.forEach((MarkerTester tester, Set<String> testNames) {
      message.write('  dart ${tester.path} -g');
      for (String testName in testNames) {
        message.write(' ${testName}');
      }
      message.writeln();
    });
  }
  message.writeln();
  if (errors.isNotEmpty) {
    Map<MarkerTester, Set<String>> erroneous = {};
    errors.forEach((String testName, Set<String> markers) {
      for (String marker in markers) {
        MarkerTester tester = markerOptions.markers[marker]!;
        (erroneous[tester] ??= {}).add(testName);
      }
    });
    message.writeln();
    if (erroneous.length > 1) {
      message.writeln('Run these commands to re-run the failing tests:');
    } else {
      message.writeln('Run this command to re-run the failing test(s):');
    }
    message.writeln();
    erroneous.forEach((MarkerTester tester, Set<String> testNames) {
      message.write('  dart ${tester.path}');
      for (String testName in testNames) {
        message.write(' ${testName}');
      }
      message.writeln();
    });
  }
  message.writeln();
  message.writeln('==========================================================');
  return message.toString();
}

/// Returns `true` if [testName] is marked as skipped in [skipMap] for
/// the given [configMarker].
bool skipForConfig(
    String testName, String configMarker, Map<String, List<String>>? skipMap) {
  if (skipMap != null) {
    List<String>? skipList = skipMap[configMarker];
    if (skipList != null && skipList.contains(testName)) {
      print("Skip: ${testName} for config '${configMarker}'");
      return true;
    }
    skipList = skipMap[null];
    if (skipList != null && skipList.contains(testName)) {
      print("Skip: ${testName} for config '${configMarker}'");
      return true;
    }
  }
  return false;
}

/// Updates all id tests in [relativeTestPaths].
///
/// This assumes that the current working directory is the repository root.
Future<void> updateAllTests(List<String> relativeTestPaths) async {
  for (String testPath in relativeTestPaths) {
    List<String> arguments = [];
    if (Platform.packageConfig != null) {
      arguments.add('--packages=${Platform.packageConfig}');
    }
    arguments.addAll([
      testPath,
      '-g',
      '--run-all',
    ]);
    print('Running: ${Platform.resolvedExecutable} ${arguments.join(' ')}');
    Process process = await Process.start(
        Platform.resolvedExecutable, arguments,
        mode: ProcessStartMode.inheritStdio);
    await process.exitCode;
  }
}
