// Copyright (c) 2012, 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.

/// Multitests are Dart test scripts containing lines of the form
/// ` [some dart code] //# [key]: [error type]`
///
/// For each key in the file, a new test file is made containing all the normal
/// lines of the file, and all of the multitest lines containing that key, in
/// the same order as in the source file. The new test is expected to pass if
/// the error type listed is 'ok', and to fail if the error type is 'syntax
/// error', 'compile-time error', 'runtime error', or 'static type warning'.
/// There is also a test created from only the
/// untagged lines of the file, with key "none", which is expected to pass. This
/// library extracts these tests, writes them into a temporary directory, and
/// passes them to the test runner. These tests may be referred to in the status
/// files with the pattern `[test name]/[key]`.
///
/// For example, file i_am_a_multitest.dart:
///
/// ```dart
/// aaa
/// bbb //# 02: runtime error
/// ccc //# 02: continued
/// ddd //# 07: static type warning
/// eee //# 10: ok
/// fff
/// ```
///
/// Create four test files:
///
/// i_am_a_multitest_none.dart:
///
/// ```dart
/// aaa
/// fff
/// ```
///
/// i_am_a_multitest_02.dart:
///
/// ```dart
/// aaa
/// bbb //# 02: runtime error
/// ccc //# 02: continued
/// fff
/// ```
///
/// i_am_a_multitest_07.dart:
///
/// ```dart
/// aaa
/// ddd //# 07: static type warning
/// fff
/// ```
///
/// i_am_a_multitest_10.dart:
///
/// ```dart
/// aaa
/// eee //# 10: ok
/// fff
/// ```
//////
/// ```dart
/// aaa
/// ddd //# 07: static type warning
/// fff
/// ```
library;

import "dart:io";

import "path.dart";
import "test_file.dart";
import "utils.dart";

final multitestMarker = "//#";

final _multitestOutcomes = {
  'ok',
  'syntax error',
  'compile-time error',
  'runtime error',
  'static type warning', // Used by some analyzer tests.
};

void _generateTestsFromMultitest(Path filePath, Map<String, String> tests,
    Map<String, Set<String>> outcomes) {
  var contents = File(filePath.toNativePath()).readAsStringSync();

  var firstNewline = contents.indexOf('\n');
  var lineSeparator =
      (firstNewline == 0 || contents[firstNewline - 1] != '\r') ? '\n' : '\r\n';
  var lines = contents.split(lineSeparator);
  if (lines.last.isEmpty) lines.removeLast();

  // Create the set of multitests, which will have a new test added each
  // time we see a multitest line with a new key.
  var testsAsLines = <String, List<String>>{};

  // Add the default case with key "none".
  testsAsLines['none'] = [];
  outcomes['none'] = {};

  var lineCount = 0;
  for (var line in lines) {
    lineCount++;
    var annotation = Annotation.tryParse(line);
    if (annotation != null) {
      testsAsLines.putIfAbsent(
          annotation.key, () => List<String>.of(testsAsLines["none"]!));
      // Add line to test with annotation.key as key, empty line to the rest.
      for (var entry in testsAsLines.entries) {
        entry.value.add(annotation.key == entry.key ? line : "");
      }
      var outcome = outcomes.putIfAbsent(annotation.key, () => <String>{});
      if (annotation.rest != 'continued') {
        for (var nextOutcome in annotation.outcomes) {
          if (_multitestOutcomes.contains(nextOutcome)) {
            outcome.add(nextOutcome);
          } else {
            DebugLogger.warning(
                "${filePath.toNativePath()}: Invalid expectation "
                "'$nextOutcome' on line $lineCount: $line");
          }
        }
      }
    } else {
      for (var test in testsAsLines.values) {
        test.add(line);
      }
    }
  }

  // End marker, has a final line separator so we don't need to add it after
  // joining the lines.
  var marker =
      '// Test created from multitest named ${filePath.toNativePath()}.'
      '$lineSeparator';
  for (var test in testsAsLines.values) {
    test.add(marker);
  }

  // Check that every test (other than the none case) has at least one outcome.
  var invalidTests =
      outcomes.keys.where((test) => test != 'none' && outcomes[test]!.isEmpty);
  for (var test in invalidTests) {
    DebugLogger.warning(
        "${filePath.toNativePath()}: Test $test has no valid expectation. "
        "Expected one of: ${_multitestOutcomes.toString()}");

    outcomes.remove(test);
    testsAsLines.remove(test);
  }

  // Copy all the tests into the output map tests, as multiline strings.
  for (var entry in testsAsLines.entries) {
    tests[entry.key] = entry.value.join(lineSeparator);
  }
}

/// Split the given [multitest] into a series of separate tests for each
/// section.
///
/// Writes the resulting tests to [outputDir] and returns a list of [TestFile]s
/// for each of those generated tests.
List<TestFile> splitMultitest(
    TestFile multitest, String outputDir, Path suiteDir,
    {bool hotReload = false}) {
  // Each key in the map tests is a multitest tag or "none", and the texts of
  // the generated test is its value.
  var tests = <String, String>{};
  var outcomes = <String, Set<String>>{};
  _generateTestsFromMultitest(multitest.path, tests, outcomes);

  var sourceDir = multitest.path.directoryPath;
  var targetDir = _createMultitestDirectory(outputDir, suiteDir, sourceDir);

  // Copy all the relative imports of the multitest.
  var importsToCopy = _findAllRelativeImports(multitest.path);
  for (var relativeImport in importsToCopy) {
    var importPath = Path(relativeImport);
    // Make sure the target directory exists.
    var importDir = importPath.directoryPath;
    if (!importDir.isEmpty) {
      TestUtils.mkdirRecursive(targetDir, importDir);
    }

    // Copy file. Because some test suites may be read-only, we don't
    // want to copy the permissions, so we create the copy by writing.
    var contents =
        File(sourceDir.join(importPath).toNativePath()).readAsBytesSync();
    File(targetDir.join(importPath).toNativePath()).writeAsBytesSync(contents);
  }

  var baseFilename = multitest.path.filenameWithoutExtension;

  var testFiles = <TestFile>[];
  for (var test in tests.entries) {
    var sectionFilePath = targetDir.append('${baseFilename}_${test.key}.dart');
    _writeFile(sectionFilePath.toNativePath(), test.value);

    var outcome = outcomes[test.key]!;
    var hasStaticWarning = outcome.contains('static type warning');
    var hasRuntimeError = outcome.contains('runtime error');
    var hasSyntaxError = outcome.contains('syntax error');
    var hasCompileError =
        hasSyntaxError || outcome.contains('compile-time error');

    if (hotReload && hasCompileError) {
      // Running a test that expects a compilation error with hot reloading
      // is redundant with a regular run of the test.
      continue;
    }

    // Create a [TestFile] for each split out section test.
    testFiles.add(multitest.split(sectionFilePath, test.key, test.value,
        hasSyntaxError: hasSyntaxError,
        hasCompileError: hasCompileError,
        hasRuntimeError: hasRuntimeError,
        hasStaticWarning: hasStaticWarning));
  }

  return testFiles;
}

/// Writes [content] to [filePath] unless there is already a file at that path
/// with the same content.
void _writeFile(String filePath, String content) {
  var file = File(filePath);

  // Don't overwrite the file if the contents are the same. This way build
  // systems don't think it has been modified.
  if (file.existsSync()) {
    var oldContent = file.readAsStringSync();
    if (oldContent == content) return;
  }

  file.writeAsStringSync(content);
}

/// A multitest annotation in the special `//#` comment.
class Annotation {
  /// Parses the annotation in [line] or returns `null` if the line isn't a
  /// multitest annotation.
  static Annotation? tryParse(String line) {
    // Do an early return with "null" if this is not a valid multitest
    // annotation.
    if (!line.contains(multitestMarker)) return null;

    var parts = line
        .split(multitestMarker)[1]
        .split(':')
        .map((s) => s.trim())
        .where((s) => s.isNotEmpty)
        .toList();

    if (parts.length <= 1) return null;

    return Annotation._(parts[0], parts[1]);
  }

  final String key;
  final String rest;

  // TODO(rnystrom): After Dart 1.0 is no longer supported, I don't think we
  // need to support more than a single outcome for each test.
  final List<String> outcomes = [];

  Annotation._(this.key, this.rest) {
    outcomes.addAll(rest.split(',').map((s) => s.trim()));
  }
}

/// Finds all relative imports and copies them into the directory with the
/// generated tests.
Set<String> _findAllRelativeImports(Path topLibrary) {
  var found = <String>{};
  var libraryDir = topLibrary.directoryPath;
  var relativeImportRegExp =
      RegExp(r'^(?:@.*\s+)?' // Allow for a meta-data annotation.
          r'(?:import|part)\s+'
          r'''["']'''
          r'(?!dart:|dart-ext:|data:|package:|/)' // Look-ahead: not in package.
          r'([^]*?)' // The path to the imported file.
          r'''["']''');

  processFile(Path filePath) {
    var file = File(filePath.toNativePath());
    for (var line in file.readAsLinesSync()) {
      var match = relativeImportRegExp.firstMatch(line);
      if (match == null) continue;
      var relativePath = match[1]!;

      // If a multitest deliberately imports a nonexistent file, don't try to
      // include it.
      if (relativePath.contains("nonexistent")) continue;

      // Handle import cycles.
      if (!found.add(relativePath)) continue;

      if (relativePath.contains("..")) {
        // This is just for safety reasons, we don't want to unintentionally
        // clobber files relative to the destination dir when copying them
        // over.
        DebugLogger.error("${filePath.toNativePath()}: "
            "Relative import in multitest containing '..' is not allowed.");
        DebugLogger.close();
        exit(1);
      }

      processFile(libraryDir.append(relativePath));
    }
  }

  processFile(topLibrary);

  return found;
}

String _suiteNameFromPath(Path suiteDir) {
  var split = suiteDir.segments();

  // co19 test suite is at tests/co19/src.
  if (split.last == 'src') split.removeLast();

  return split.last;
}

Path _createMultitestDirectory(
    String outputDir, Path suiteDir, Path sourceDir) {
  var relative = sourceDir.relativeTo(suiteDir);
  var path = Path(outputDir)
      .append('generated_tests')
      .append(_suiteNameFromPath(suiteDir))
      .join(relative);
  TestUtils.mkdirRecursive(Path.workingDirectory, path);
  return Path(File(path.toNativePath()).absolute.path);
}
