// @dart = 2.9

import 'dart:convert';
import 'dart:typed_data';

import 'package:_fe_analyzer_shared/src/scanner/token.dart';
import 'package:front_end/src/api_prototype/memory_file_system.dart';
import 'package:front_end/src/fasta/hybrid_file_system.dart';

import "../tool/dart_doctest_impl.dart" as impl;

main() async {
  expectCategory = "comment extraction";
  testCommentExtraction();

  expectCategory = "test extraction";
  testTestExtraction();

  expectCategory = "test runs";
  await testRunningTests();
}

void testRunningTests() async {
  MemoryFileSystem memoryFileSystem =
      new MemoryFileSystem(new Uri(scheme: "darttest", path: "/"));
  HybridFileSystem hybridFileSystem = new HybridFileSystem(memoryFileSystem);
  impl.DartDocTest dartDocTest = new impl.DartDocTest(
      underlyingFileSystem: hybridFileSystem, silent: true);

  // Good test
  Uri test1 = new Uri(scheme: "darttest", path: "/test1.dart");
  String test = """
  // DartDocTest(1+1, 2)
  main() {
    print("Hello from main");
  }

  // DartDocTest(_internal(), 42)
  int _internal() {
    return 42;
  }
  """;
  List<impl.Test> tests = extractTests(test, test1);
  expect(tests.length, 2);
  List<impl.TestResult> expected = [
    new impl.TestResult(tests[0], impl.TestOutcome.Pass),
    new impl.TestResult(tests[1], impl.TestOutcome.Pass),
  ];
  memoryFileSystem.entityForUri(test1).writeAsStringSync(test);
  expect(await dartDocTest.process(test1), expected);

// Mixed good/bad.
  Uri test2 = new Uri(scheme: "darttest", path: "/test2.dart");
  test = """
// DartDocTest(1+1, 3)
main() {
  print("Hello from main");
}

// DartDocTest(_internal(), 43)
// DartDocTest(_internal(), 42)
int _internal() {
  return 42;
}
""";
  tests = extractTests(test, test2);
  expect(tests.length, 3);
  expected = [
    new impl.TestResult(tests[0], impl.TestOutcome.Failed)
      ..message = "Expected '3'; got '2'.",
    new impl.TestResult(tests[1], impl.TestOutcome.Failed)
      ..message = "Expected '43'; got '42'.",
    new impl.TestResult(tests[2], impl.TestOutcome.Pass),
  ];
  memoryFileSystem.entityForUri(test2).writeAsStringSync(test);
  expect(await dartDocTest.process(test2), expected);

// Good case using await.
  Uri test3 = new Uri(scheme: "darttest", path: "/test3.dart");
  test = """
// DartDocTest(await _internal(), 42)
Future<int> _internal() async {
  await Future.delayed(new Duration(milliseconds: 1));
  return 42;
}
""";
  tests = extractTests(test, test3);
  expect(tests.length, 1);
  expected = [
    new impl.TestResult(tests[0], impl.TestOutcome.Pass),
  ];
  memoryFileSystem.entityForUri(test3).writeAsStringSync(test);
  expect(await dartDocTest.process(test3), expected);

// One test parse error and one good case.
  Uri test4 = new Uri(scheme: "darttest", path: "/test4.dart");
  test = """
// DartDocTest(_internal() 42)
// DartDocTest(_internal(), 42)
int _internal() {
  return 42;
}
""";
  tests = extractTests(test, test4);
  expect(tests.length, 2);
  expected = [
    new impl.TestResult(tests[0], impl.TestOutcome.TestCompilationError)
      ..message = "Parse error @ 27",
    new impl.TestResult(tests[1], impl.TestOutcome.Pass),
  ];
  memoryFileSystem.entityForUri(test4).writeAsStringSync(test);
  expect(await dartDocTest.process(test4), expected);

// Test with compile-time error. Note that this means no tests are compiled at
// all and that while the error messages are passed it spills the internals of
// the dartdocs stuff (e.g. points to lines that doesn't exist because we added
// them, specifies 'dartDocTest.test' etc).
  Uri test5 = new Uri(scheme: "darttest", path: "/test5.dart");
  test = """
// DartDocTest(_internal() + 2, 42)
// // DartDocTest(2+2, 4)
void _internal() {
  return;
}
""";
  tests = extractTests(test);
  expect(tests.length, 2);
  expected = [
    new impl.TestResult(null, impl.TestOutcome.CompilationError)
      ..message =
          """darttest:/test5.dart:9:20: Error: This expression has type 'void' and can't be used.
  dartDocTest.test(_internal() + 2, 42);
                   ^
darttest:/test5.dart:9:32: Error: The operator '+' isn't defined for the class 'void'.
Try correcting the operator to an existing operator, or defining a '+' operator.
  dartDocTest.test(_internal() + 2, 42);
                               ^""",
  ];
  memoryFileSystem.entityForUri(test5).writeAsStringSync(test);
  expect(await dartDocTest.process(test5), expected);

  // Test with runtime error.
  Uri test6 = new Uri(scheme: "darttest", path: "/test6.dart");
  test = """
// DartDocTest(_internal() + 2, 42)
// // DartDocTest(2+2, 4)
dynamic _internal() {
  return "hello";
}
""";
  tests = extractTests(test);
  expect(tests.length, 2);
  expected = [
    new impl.TestResult(tests[0], impl.TestOutcome.Crash)
      // this weird message is from the VM!
      ..message = "type 'int' is not a subtype of type 'String' of 'other'",
    new impl.TestResult(tests[1], impl.TestOutcome.Pass),
  ];
  memoryFileSystem.entityForUri(test6).writeAsStringSync(test);
  expect(await dartDocTest.process(test6), expected);
}

void testTestExtraction() {
  // No tests.
  expect(extractTests(""), <impl.Test>[]);

  // One test.
  expect(extractTests("// DartDocTest(1+1, 2)"), <impl.Test>[
    new impl.ExpectTest("1+1", "2"),
  ]);

  // Two tests.
  expect(extractTests("""
// DartDocTest(1+1, 2)
// DartDocTest(2+40, 42)
"""), <impl.Test>[
    new impl.ExpectTest("1+1", "2"),
    new impl.ExpectTest("2+40", "42"),
  ]);

  // Two valid tests. Four invalid ones.
  expect(extractTests("""
// DartDocTest(1+1, 2)
// DartDocTest(2+40; 42]
// DartDocTest(2+40+, 42]
// DartDocTest(2+40, 42]
// DartDocTest(2+40, 42)
// DartDocTest(2+40, 42+)
"""), <impl.Test>[
    new impl.ExpectTest("1+1", "2"),
    new impl.TestParseError(
        """darttest:/foo.dart:2:20: Expected ',' before this.
// DartDocTest(2+40; 42]
                   ^""", 42),
    new impl.TestParseError("""Parse error(s):

darttest:/foo.dart:3:21: Expected an identifier, but got ','.
// DartDocTest(2+40+, 42]
                    ^""", 68),
    new impl.TestParseError(
        """darttest:/foo.dart:4:24: Expected ')' before this.
// DartDocTest(2+40, 42]
                       ^""", 97),
    new impl.ExpectTest("2+40", "42"),
    new impl.TestParseError("""Parse error(s):

darttest:/foo.dart:6:25: Expected an identifier, but got ')'.
// DartDocTest(2+40, 42+)
                        ^""", 148),
  ]);

  // Two tests in block comments with back-ticks around tests.
  expect(extractTests("""
/**
 * This is a test:
 * ```
 * DartDocTest(1+1, 2)
 * ```
 * and so is this:
 * ```
 * DartDocTest(2+40, 42)
 * ```
 */
"""), <impl.Test>[
    new impl.ExpectTest("1+1", "2"),
    new impl.ExpectTest("2+40", "42"),
  ]);

  // Two tests --- include linebreaks.
  expect(extractTests("""
/*
  This is a test:
  DartDocTest(1+1,
    2)
  and so is this:
  DartDocTest(2+
  40,
  42)
 */
"""), <impl.Test>[
    new impl.ExpectTest("1+1", "2"),
    // The linebreak etc here is not stripped (at the moment at least)
    new impl.ExpectTest("2+\n  40", "42"),
  ]);

  // Two tests --- with parens and commas as string...
  expect(extractTests("""
// DartDocTest("(", "(")
// and so is this:
// DartDocTest(",)", ",)")
"""), <impl.Test>[
    new impl.ExpectTest('"("', '"("'),
    new impl.ExpectTest('",)"', '",)"'),
  ]);

  // Await expression.
  expect(extractTests("""
// DartDocTest(await foo(), 42)
"""), <impl.Test>[
    new impl.ExpectTest('await foo()', '42'),
  ]);
}

void testCommentExtraction() {
  // No comment
  expect(extractFirstComment(""), null);

  // Simple line comment at position 0.
  expect(
      extractFirstComment("// Hello"), new impl.CommentString("   Hello", 0));

  // Simple line comment at position 5.
  expect(extractFirstComment("     // Hello"),
      new impl.CommentString("   Hello", 5));

  // Multiline simple comment at position 20.
  expect(extractFirstComment("""
import 'foo.dart';

// This is
// a
// multiline
// comment

import 'bar.dart'"""), new impl.CommentString("""
   This is
   a
   multiline
   comment""", 20));

  // Multiline simple comment (with 3 slashes) at position 20.
  expect(extractFirstComment("""
import 'foo.dart';

/// This is
/// a
/// multiline
/// comment

import 'bar.dart'"""), new impl.CommentString("""
    This is
    a
    multiline
    comment""", 20));

  // Multiline comments with /* at position 20.
  expect(extractFirstComment("""
import 'foo.dart';

/* This is
a
 multiline
comment
*/

import 'bar.dart'"""), new impl.CommentString("""
   This is
a
 multiline
comment
  """, 20));

  // Multiline comments with /* at position 20. Note that the comment has
  // * at the start of the line but that they aren't stripped because the
  // comments starts with /* and NOT with /**.
  expect(extractFirstComment("""
import 'foo.dart';

/* This is
*a
* multiline
*comment
*/

import 'bar.dart'"""), new impl.CommentString("""
   This is
*a
* multiline
*comment
  """, 20));

  // Multiline comments with /** */ at position 20. Note that the comment has
  // * at the start of the line and that they are stripped because the
  // comments starts with /** and NOT with only /*.
  expect(extractFirstComment("""
import 'foo.dart';

/** This is
*a
* multiline
*comment
*/

import 'bar.dart'"""), new impl.CommentString("""
    This is
 a
  multiline
 comment
  """, 20));

  // Multiline comment with block comment inside at position 20.
  // The block comment data is not stripped.
  expect(extractFirstComment("""
import 'foo.dart';

/// This is
/// /*a*/
/// multiline comment"""), new impl.CommentString("""
    This is
    /*a*/
    multiline comment""", 20));
}

int expectCalls = 0;
String expectCategory;

void expect(dynamic actual, dynamic expected) {
  expectCalls++;
  StringBuffer sb = new StringBuffer();
  if (!_expectImpl(actual, expected, sb)) {
    if (sb.isNotEmpty) {
      throw "Error! Expected '$expected' but got '$actual'"
          "\n\n"
          "Explanation: $sb.";
    } else {
      throw "Error! Expected '$expected' but got '$actual'";
    }
  }
  print("Expect #$expectCalls ($expectCategory) OK.");
}

bool _expectImpl(dynamic actual, dynamic expected, StringBuffer explainer) {
  if (identical(actual, expected)) return true;
  if (actual == expected) return true;
  if (actual == null || expected == null) return false;
  if (actual is List && expected is List) {
    if (actual.runtimeType != expected.runtimeType) {
      explainer.write("List runtimeType difference: "
          "${actual.runtimeType} vs ${expected.runtimeType}");
      return false;
    }
    if (actual.length != expected.length) {
      explainer.write("List length difference: "
          "${actual.length} vs ${expected.length}");
      return false;
    }
    for (int i = 0; i < actual.length; i++) {
      if (actual[i] != expected[i]) {
        explainer.write("List difference at index $i: "
            "${actual[i]} vs ${expected[i]}");
        return false;
      }
    }
    return true;
  }
  if (actual is List || expected is List) return false;

  if (actual is Map && expected is Map) {
    if (actual.runtimeType != expected.runtimeType) return false;
    if (actual.length != expected.length) return false;
    for (dynamic key in actual.keys) {
      if (!expected.containsKey(key)) return false;
      if (actual[key] != expected[key]) return false;
    }
    return true;
  }
  if (actual is Map || expected is Map) return false;

  if (actual is Set && expected is Set) {
    if (actual.runtimeType != expected.runtimeType) return false;
    if (actual.length != expected.length) return false;
    for (dynamic value in actual) {
      if (!expected.contains(value)) return false;
    }
    return true;
  }
  if (actual is Set || expected is Set) return false;

  // More stuff?
  return false;
}

impl.CommentString extractFirstComment(String test) {
  Token firstToken = impl.scanRawBytes(utf8.encode(test) as Uint8List);
  Token token = firstToken;
  while (true) {
    CommentToken comment = token.precedingComments;
    if (comment != null) {
      return impl.extractComments(comment, test);
    }
    if (token.isEof) break;
    Token next = token.next;
    if (next == null) break;
    token = next;
  }
  return null;
}

List<impl.Test> extractTests(String test, [Uri uri]) {
  return impl.extractTests(utf8.encode(test) as Uint8List,
      uri ?? new Uri(scheme: "darttest", path: "/foo.dart"));
}
