// 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 = RegExp(r"//[#/]");
  static int _multitestMarkerLength = 3;

  static const List<String> validOutcomesList = <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 = 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": 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, () => List<String>.from(linesWithoutAnnotations));
          lines.add(line);
          Set<String> subtestOutcomes =
              outcomes.putIfAbsent(subtestName, () => 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 =
          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 =
            FileBasedTestDescription(root, File.fromUri(uri));
        subtest.multitestExpectations = outcomes[name];
        await subtest.file.writeAsString(lines.join(""));
        yield subtest;
      }
    }
    if (errors.isNotEmpty) {
      throw "Error: ${errors.join("\n")}";
    }
  }
}
