// 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;

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,
    {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];
    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,
    {Iterable<String> supportedMarkers,
    Uri createTestUri(Uri uri, String fileName),
    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.");
  }

  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) {
    actualData ??= '';
    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>(
    String modeName,
    Uri mainFileUri,
    Map<Uri, AnnotatedCode> code,
    MemberAnnotations<IdValue> expectedMaps,
    CompiledData<T> compiledData,
    DataInterpreter<T> dataInterpreter,
    {bool filterActualData(IdValue expected, ActualData<T> actualData),
    bool fatalErrors: true,
    bool succinct: false,
    void onFailure(String message)}) async {
  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;
      if (uri != null) {
        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])
            .toText());
        print('----------------------------------------------------------');
      }
    }
  }
  if (missingIds.isNotEmpty) {
    print("MISSING ids: ${missingIds}.");
    hasFailure = true;
  }
  if (hasFailure && fatalErrors) {
    onFailure('Errors found.');
  }
  return new TestResult<T>(dataInterpreter, compiledData, hasFailure);
}

typedef Future<Map<String, TestResult<T>>> RunTestFunction<T>(TestData testData,
    {bool testAfterFailures,
    bool verbose,
    bool succinct,
    bool printCode,
    Map<String, List<String>> skipMap,
    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('/')
  ]);
}

class MarkerOptions {
  final Map<String, Uri> 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, Uri> 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] = 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<Uri> testers = markers.values.toSet();
    bool allOk = true;
    for (Uri tester in testers) {
      print('================================================================');
      print('Running tester: $tester ${args.join(' ')}');
      print('================================================================');
      Process process = await Process.start(
          Platform.resolvedExecutable, [tester.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;
  }
}

/// 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),
    Uri createUriForFileName(String fileName),
    void onFailure(String message),
    RunTestFunction<T> runTest,
    List<String> skipList,
    Map<String, List<String>> skipMap,
    bool preserveWhitespaceInAnnotations: false,
    bool preserveInfixWhitespaceInAnnotations: false}) async {
  MarkerOptions markerOptions =
      new MarkerOptions.fromDataDir(dataDir, shouldFindScript: shards == 1);
  // TODO(johnniwinther): Support --show to show actual data for an input.
  args = args.toList();
  bool runAll = args.remove('--run-all');
  if (runAll) {
    await markerOptions.runAll(args);
    return;
  }
  bool verbose = args.remove('-v');
  bool succinct = args.remove('-s');
  bool shouldContinue = args.remove('-c');
  bool testAfterFailures = args.remove('-a');
  bool printCode = args.remove('-p');
  bool continued = false;
  bool hasFailures = false;
  bool generateAnnotations = args.remove('-g');
  bool forceUpdate = args.remove('-f');

  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'))
      .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 name = getTestName(entity);
    if (args.isNotEmpty && !args.contains(name) && !continued) continue;
    if (shouldContinue) continued = true;
    testCount++;

    if (skipList != null && skipList.contains(name) && !args.contains(name)) {
      print('Skip: ${name}');
      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(testData,
        testAfterFailures: testAfterFailures || generateAnnotations,
        verbose: verbose,
        succinct: succinct,
        printCode: printCode,
        skipMap: skipMap,
        nullUri: createTestUri(entity.uri.resolve("null"), "null"));

    bool hasMismatches = false;
    bool hasErrors = false;
    results.forEach((String marker, TestResult<T> result) {
      if (result.hasMismatches) {
        hasMismatches = true;
      } else if (result.isErroneous) {
        hasErrors = true;
      }
    });
    if (hasErrors) {
      // Cannot generate annotations for erroneous tests.
      hasFailures = true;
    } else if (hasMismatches || (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(uri != null && testData.code.containsKey(uri) ||
                actualData.isEmpty);
            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) {
          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 {
        hasFailures = true;
      }
    }
  }
  if (hasFailures) {
    onFailure('Errors found.');
  }
  if (testCount == 0) {
    onFailure("No files were tested.");
  }
}

/// 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 = [
      '--packages=${Platform.packageConfig}',
      testPath,
      '-g',
      '--run-all'
    ];
    print('Running: ${Platform.resolvedExecutable} ${arguments.join(' ')}');
    Process process = await Process.start(
        Platform.resolvedExecutable, arguments,
        mode: ProcessStartMode.inheritStdio);
    await process.exitCode;
  }
}
