// Copyright (c) 2016, 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.md file.

library testing.multitest;

import 'dart:async' show Stream, StreamTransformerBase;

import 'dart:io' show Directory, File;

import 'log.dart' show splitLines;

import 'test_description.dart' show FileBasedTestDescription, TestDescription;

bool isError(Set<String> expectations) {
  if (expectations.contains("compile-time error")) return true;
  if (expectations.contains("runtime error")) return true;
  return false;
}

bool isCheckedModeError(Set<String> expectations) {
  if (expectations.contains("checked mode compile-time error")) return true;
  if (expectations.contains("dynamic type error")) return true;
  return isError(expectations);
}

class MultitestTransformer
    extends StreamTransformerBase<TestDescription, TestDescription> {
  static RegExp multitestMarker = new RegExp(r"//[#/]");
  static int _multitestMarkerLength = 3;

  static const List<String> validOutcomesList = const <String>[
    "ok",
    "syntax error",
    "compile-time error",
    "runtime error",
    "static type warning",
    "dynamic type error",
    "checked mode compile-time error",
  ];

  static final Set<String> validOutcomes =
      new Set<String>.from(validOutcomesList);

  Stream<TestDescription> bind(Stream<TestDescription> stream) async* {
    List<String> errors = <String>[];
    reportError(String error) {
      errors.add(error);
      print(error);
    }

    nextTest:
    await for (TestDescription test in stream) {
      FileBasedTestDescription? multitest;
      String? contents;
      if (test is FileBasedTestDescription) {
        contents = await test.file.readAsString();
        if (contents.contains(multitestMarker)) {
          multitest = test;
        }
      }

      if (multitest == null) {
        yield test;
        continue nextTest;
      }
      // Note: this is modified in the loop below.
      List<String> linesWithoutAnnotations = <String>[];
      Map<String, List<String>> testsAsLines = <String, List<String>>{
        "none": linesWithoutAnnotations,
      };
      Map<String, Set<String>> outcomes = <String, Set<String>>{
        "none": new Set<String>(),
      };
      int lineNumber = 0;
      for (String line in splitLines(contents!)) {
        lineNumber++;
        int index = line.indexOf(multitestMarker);
        String? subtestName;
        List<String>? subtestOutcomesList;
        if (index != -1) {
          String annotationText =
              line.substring(index + _multitestMarkerLength).trim();
          index = annotationText.indexOf(":");
          if (index != -1) {
            subtestName = annotationText.substring(0, index).trim();
            subtestOutcomesList = annotationText
                .substring(index + 1)
                .split(",")
                .map((s) => s.trim())
                .toList();
            if (subtestOutcomesList.isEmpty) {
              reportError(multitest
                  .formatError("$lineNumber: Expected <testname>:<outcomes>"));
              continue nextTest;
            }
          }
        }
        if (subtestName != null) {
          List<String> lines = testsAsLines.putIfAbsent(subtestName,
              () => new List<String>.from(linesWithoutAnnotations));
          lines.add(line);
          Set<String> subtestOutcomes =
              outcomes.putIfAbsent(subtestName, () => new Set<String>());
          if (subtestOutcomesList!.length != 1 ||
              subtestOutcomesList.single != "continued") {
            for (String outcome in subtestOutcomesList) {
              if (validOutcomes.contains(outcome)) {
                subtestOutcomes.add(outcome);
              } else {
                reportError(multitest.formatError(
                    "$lineNumber: '$outcome' isn't a recognized outcome."));
                continue nextTest;
              }
            }
          }
        } else {
          for (List<String> lines in testsAsLines.values) {
            // This will also modify [linesWithoutAnnotations].
            lines.add(line);
          }
        }
      }
      Uri root = Uri.base.resolve("generated/");
      Directory generated =
          new Directory.fromUri(root.resolve(multitest.shortName));
      generated = await generated.create(recursive: true);
      for (MapEntry<String, List<String>> entry in testsAsLines.entries) {
        String name = entry.key;
        List<String> lines = entry.value;
        Uri uri = generated.uri.resolve("${name}_generated.dart");
        FileBasedTestDescription subtest =
            new FileBasedTestDescription(root, new File.fromUri(uri));
        subtest.multitestExpectations = outcomes[name];
        await subtest.file.writeAsString(lines.join(""));
        yield subtest;
      }
    }
    if (errors.isNotEmpty) {
      throw "Error: ${errors.join("\n")}";
    }
  }
}
