// Copyright (c) 2021, 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:async';
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'dart:typed_data';

import 'package:_fe_analyzer_shared/src/parser/parser.dart' show Parser;

import 'package:_fe_analyzer_shared/src/messages/codes.dart' as codes;

import 'package:_fe_analyzer_shared/src/parser/async_modifier.dart'
    show AsyncModifier;

import 'package:_fe_analyzer_shared/src/parser/forwarding_listener.dart'
    show NullListener;

import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
    show ScannerConfiguration;

import 'package:_fe_analyzer_shared/src/scanner/token.dart';

import 'package:_fe_analyzer_shared/src/scanner/utf8_bytes_scanner.dart'
    show Utf8BytesScanner;

import 'package:front_end/src/api_prototype/compiler_options.dart';
import 'package:front_end/src/api_prototype/file_system.dart';
import 'package:front_end/src/api_prototype/memory_file_system.dart';
import 'package:front_end/src/api_prototype/standard_file_system.dart';
import 'package:front_end/src/base/processed_options.dart';
import 'package:front_end/src/fasta/builder/library_builder.dart';
import 'package:front_end/src/fasta/combinator.dart';

import 'package:front_end/src/fasta/command_line_reporting.dart'
    as command_line_reporting;

import 'package:front_end/src/fasta/compiler_context.dart';
// ignore: import_of_legacy_library_into_null_safe
import 'package:front_end/src/fasta/dill/dill_library_builder.dart';
// ignore: import_of_legacy_library_into_null_safe
import 'package:front_end/src/fasta/dill/dill_target.dart';
import 'package:front_end/src/fasta/fasta_codes.dart';
import 'package:front_end/src/fasta/hybrid_file_system.dart';
// ignore: import_of_legacy_library_into_null_safe
import 'package:front_end/src/fasta/incremental_compiler.dart';
import 'package:front_end/src/fasta/kernel/utils.dart';
import 'package:front_end/src/fasta/source/diet_parser.dart'
    show useImplicitCreationExpressionInCfe;
// ignore: import_of_legacy_library_into_null_safe
import 'package:front_end/src/fasta/source/source_library_builder.dart';
import 'package:front_end/src/fasta/uri_translator.dart';
import 'package:kernel/kernel.dart' as kernel
    show Combinator, Component, LibraryDependency, Library, Location, Source;
import 'package:kernel/target/targets.dart';
// ignore: import_of_legacy_library_into_null_safe
import 'package:vm/target/vm.dart';

// ignore: import_of_legacy_library_into_null_safe
import '../test/incremental_suite.dart' show getOptions;

const _portMessageTest = "test";
const _portMessageGood = "good";
const _portMessageBad = "bad";
const _portMessageCrash = "crash";
const _portMessageParseError = "parseError";
const _portMessageDone = "done";

// TODO: This doesn't work on parts... (Well, it might, depending on how
// the part declares what file it's part of and if we've compiled other stuff
// first so we know more stuff).
class DartDocTest {
  DocTestIncrementalCompiler? incrementalCompiler;
  late CompilerOptions options;
  late ProcessedOptions processedOpts;
  bool errors = false;
  List<String> errorStrings = [];
  final FileSystem? underlyingFileSystem;
  final bool silent;

  DartDocTest({this.underlyingFileSystem, this.silent: false});

  FileSystem _getFileSystem() =>
      underlyingFileSystem ?? StandardFileSystem.instance;

  void _print(Object? object) {
    if (!silent) print(object);
  }

  /// All-in-one. Process a file and return if it was good.
  Future<List<TestResult>> process(Uri uri) async {
    _print("\n\nProcessing $uri");
    Stopwatch stopwatch = new Stopwatch()..start();

    // Extract test cases in file.
    List<Test> tests = await extractTestsFromUri(uri);

    if (tests.isEmpty) {
      _print("No tests found in file in ${stopwatch.elapsedMilliseconds} ms.");
      return [];
    }
    _print("Found ${tests.length} test(s) in file "
        "in ${stopwatch.elapsedMilliseconds} ms.");

    return await compileAndRun(uri, tests);
  }

  Future<List<Test>> extractTestsFromUri(Uri uri) async {
    // Extract test cases in file.
    FileSystemEntity file = _getFileSystem().entityForUri(uri);
    List<int> rawBytes = await file.readAsBytes();
    return extractTests(
        rawBytes is Uint8List ? rawBytes : new Uint8List.fromList(rawBytes),
        uri);
  }

  Future<List<TestResult>> compileAndRun(Uri uri, List<Test> tests,
      {bool silent: false}) async {
    errors = false;
    errorStrings.clear();

    // Create code to amend the file with.
    StringBuffer sb = new StringBuffer();
    if (tests.isNotEmpty) {
      sb.writeln(
          r"Future<void> $dart$doc$test$tester(dynamic dartDocTest) async {");
      for (Test test in tests) {
        if (test is TestParseError) {
          sb.writeln(
              "dartDocTest.parseError(\"Parse error @ ${test.position}\");");
        } else if (test is ExpectTest) {
          sb.writeln("try {");
          sb.writeln("  dartDocTest.test(${test.call}, ${test.result});");
          sb.writeln("} catch (e) {");
          sb.writeln("  dartDocTest.crash(e);");
          sb.writeln("}");
        } else {
          throw "Unknown test type: ${test.runtimeType}";
        }
      }
      sb.writeln("}");
    }

    if (incrementalCompiler == null) {
      setupIncrementalCompiler(uri);
    }

    processedOpts.inputs.clear();
    processedOpts.inputs.add(uri);
    HybridFileSystem fileSystem = new HybridFileSystem(
        new MemoryFileSystem(new Uri(scheme: "dartdoctest", path: "/")),
        _getFileSystem());
    options.fileSystem = fileSystem;
    processedOpts.clearFileSystemCache();
    // Invalidate package uri to force re-finding of packages
    // (e.g. if we're now compiling somewhere else).
    incrementalCompiler!.invalidate(processedOpts.packagesUri);

    Stopwatch stopwatch = new Stopwatch()..start();
    kernel.Component component =
        await incrementalCompiler!.computeDelta(entryPoints: [uri]);
    if (errors) {
      _print("Got errors in ${stopwatch.elapsedMilliseconds} ms.");
      return [
        new TestResult(null, TestOutcome.CompilationError)
          ..message = errorStrings.join("\n")
      ];
    }
    _print("Compiled (1) in ${stopwatch.elapsedMilliseconds} ms.");
    stopwatch.reset();

    await incrementalCompiler!.compileDartDocTestLibrary(
        sb.toString(), component.uriToSource[uri]?.importUri ?? uri);

    final Uri dartDocMainUri = new Uri(scheme: "dartdoctest", path: "main");
    fileSystem.memory
        .entityForUri(dartDocMainUri)
        .writeAsStringSync(mainFileContent);

    incrementalCompiler!.invalidate(dartDocMainUri);
    kernel.Component componentMain = await incrementalCompiler!
        .computeDelta(entryPoints: [dartDocMainUri], fullComponent: true);
    if (errors) {
      _print("Got errors in ${stopwatch.elapsedMilliseconds} ms.");
      return [
        new TestResult(null, TestOutcome.CompilationError)
          ..message = errorStrings.join("\n")
      ];
    }
    _print("Compiled (2) in ${stopwatch.elapsedMilliseconds} ms.");
    stopwatch.reset();

    Directory tmpDir = Directory.systemTemp.createTempSync();
    Uri dillOutUri = tmpDir.uri.resolve("dartdoctestrun.dill");
    await writeComponentToFile(componentMain, dillOutUri);
    _print("Wrote dill in ${stopwatch.elapsedMilliseconds} ms.");
    stopwatch.reset();

    // Spawn URI (dill uri) to run tests.
    ReceivePort exitPort = new ReceivePort();
    ReceivePort errorPort = new ReceivePort();
    ReceivePort communicationPort = new ReceivePort();
    Completer<dynamic> completer = new Completer();
    bool error = false;
    exitPort.listen((message) {
      exitPort.close();
      errorPort.close();
      communicationPort.close();
      completer.complete();
    });
    errorPort.listen((message) {
      _print("Isolate had an error: $message.");
      error = true;
      exitPort.close();
      errorPort.close();
      communicationPort.close();
      completer.complete();
    });
    int testCount = 0;
    int goodCount = 0;
    int badCount = 0;
    int crashCount = 0;
    int parseErrorCount = 0;
    bool done = false;
    Test? currentTest;

    List<TestResult> result = [];

    communicationPort.listen((message) {
      if (done) {
        throw "Didn't expect any more messages. Got '$message'";
      }
      if (message == _portMessageTest) {
        currentTest = tests[testCount];
        testCount++;
      } else if (message == _portMessageGood) {
        goodCount++;
        result.add(new TestResult(currentTest!, TestOutcome.Pass));
      } else if (message.toString().startsWith("$_portMessageBad: ")) {
        badCount++;
        String strippedMessage =
            message.toString().substring("$_portMessageBad: ".length);
        result.add(new TestResult(currentTest!, TestOutcome.Failed)
          ..message = strippedMessage);
        _print(strippedMessage);
      } else if (message.toString().startsWith("$_portMessageCrash: ")) {
        String strippedMessage =
            message.toString().substring("$_portMessageCrash: ".length);
        result.add(new TestResult(currentTest!, TestOutcome.Crash)
          ..message = strippedMessage);
        crashCount++;
        _print(strippedMessage);
      } else if (message.toString().startsWith("$_portMessageParseError: ")) {
        String strippedMessage =
            message.toString().substring("$_portMessageParseError: ".length);
        result.add(
            new TestResult(currentTest!, TestOutcome.TestCompilationError)
              ..message = strippedMessage);
        parseErrorCount++;
        _print(strippedMessage);
      } else if (message == _portMessageDone) {
        done = true;
        // don't complete completer here. Expect the exit port to close.
      } else {
        throw "Didn't expect '$message'";
      }
    });
    // TODO: Possibly it should be launched in a process instead so we can
    // (sort of) catch and report exit calls in test code.
    await Isolate.spawnUri(
      dillOutUri,
      [],
      communicationPort.sendPort,
      onExit: exitPort.sendPort,
      onError: errorPort.sendPort,
    );
    await completer.future;
    tmpDir.deleteSync(recursive: true);

    if (error) {
      _print("Completed with an error in ${stopwatch.elapsedMilliseconds} ms.");
      return [new TestResult(null, TestOutcome.RuntimeError)];
    } else if (!done) {
      _print(
          "Didn't complete correctly in ${stopwatch.elapsedMilliseconds} ms.");
      return [new TestResult(null, TestOutcome.FrameworkError)];
    } else if (testCount != tests.length) {
      _print("Didn't complete with error but ran "
          "${testCount} tests while expecting ${tests.length} "
          "in ${stopwatch.elapsedMilliseconds} ms.");
      return [new TestResult(null, TestOutcome.FrameworkError)];
    } else {
      _print("Processed $testCount test(s) "
          "in ${stopwatch.elapsedMilliseconds} ms.");
      if (goodCount == testCount &&
          badCount == 0 &&
          crashCount == 0 &&
          parseErrorCount == 0) {
        _print("All tests passed.");
      } else {
        _print("$goodCount OK; "
            "$badCount bad; "
            "$crashCount crashed; "
            "$parseErrorCount parse errors.");
      }
      return result;
    }
  }

  void setupIncrementalCompiler(Uri uri) {
    options = getOptions();
    TargetFlags targetFlags = new TargetFlags(enableNullSafety: true);
    // TODO: Target could possible be something else...
    Target target = new VmTarget(targetFlags);
    options.target = target;
    options.omitPlatform = true;
    options.onDiagnostic = (DiagnosticMessage message) {
      if (message.codeName == "InferredPackageUri") return;
      _print(message.plainTextFormatted.first);
      if (message.severity == Severity.error) {
        errors = true;
        for (String errorString in message.plainTextFormatted) {
          errorStrings.add(errorString);
        }
      }
    };
    processedOpts = new ProcessedOptions(options: options, inputs: [uri]);
    CompilerContext compilerContext = new CompilerContext(processedOpts);
    this.incrementalCompiler = new DocTestIncrementalCompiler(compilerContext);
  }
}

final String mainFileContent = """
// Copyright (c) 2021, 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.

// @dart = 2.9

import "${DocTestIncrementalCompiler.dartDocTestUri}" as tester;
import "dart:isolate";

Future<void> main(List<String> args, SendPort port) async {
  DartDocTest test = new DartDocTest(port);
  await tester.\$dart\$doc\$test\$tester(test);
  port.send("$_portMessageDone");
}

class DartDocTest {
  final SendPort port;

  DartDocTest(this.port);

  void test(dynamic actual, dynamic expected) {
    port.send("$_portMessageTest");
    if (_testImpl(actual, expected)) {
      port.send("$_portMessageGood");
    } else {
      port.send("$_portMessageBad: Expected '\$expected'; got '\$actual'.");
    }
  }

  void crash(dynamic error) {
    port.send("$_portMessageTest");
    port.send("$_portMessageCrash: \$error");
  }

  void parseError(String message) {
    port.send("$_portMessageTest");
    port.send("$_portMessageParseError: \$message");
  }

  bool _testImpl(dynamic actual, dynamic expected) {
    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) return false;
      if (actual.length != expected.length) return false;
      for (int i = 0; i < actual.length; i++) {
        if (actual[i] != 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;
  }
}
""";

List<Test> extractTests(Uint8List rawBytes, Uri uriForReporting) {
  String rawString = utf8.decode(rawBytes);
  List<int> lineStarts = [];
  Token firstToken = scanRawBytes(rawBytes, lineStarts: lineStarts);
  kernel.Source source =
      new kernel.Source(lineStarts, rawBytes, uriForReporting, uriForReporting);
  Token token = firstToken;
  List<Test> tests = [];
  while (true) {
    CommentToken? comment = token.precedingComments;
    if (comment != null) {
      tests.addAll(extractTestsFromComment(comment, rawString, source));
    }
    if (token.isEof) break;
    Token? next = token.next;
    if (next == null) break;
    token = next;
  }
  return tests;
}

Token scanRawBytes(Uint8List rawBytes, {List<int>? lineStarts}) {
  Uint8List bytes = new Uint8List(rawBytes.length + 1);
  bytes.setRange(0, rawBytes.length, rawBytes);

  ScannerConfiguration scannerConfiguration = new ScannerConfiguration(
      enableExtensionMethods: true,
      enableNonNullable: true,
      enableTripleShift: true);

  Utf8BytesScanner scanner = new Utf8BytesScanner(
    bytes,
    includeComments: true,
    configuration: scannerConfiguration,
    languageVersionChanged: (scanner, languageVersion) {
      // For now don't do anything, but having it (making it non-null) means the
      // configuration won't be reset.
    },
  );
  Token result = scanner.tokenize();
  if (lineStarts != null) {
    lineStarts.clear();
    lineStarts.addAll(scanner.lineStarts);
  }
  return result;
}

const int $LF = 10;
const int $SPACE = 32;
const int $STAR = 42;

class Test {}

class ExpectTest implements Test {
  final String call;
  final String result;

  ExpectTest(this.call, this.result);

  @override
  bool operator ==(Object other) {
    if (other is! ExpectTest) return false;
    if (other.call != call) return false;
    if (other.result != result) return false;
    return true;
  }

  @override
  String toString() {
    return "ExpectTest[$call, $result]";
  }
}

class TestParseError implements Test {
  final String message;
  final int position;

  TestParseError(this.message, this.position);

  @override
  bool operator ==(Object other) {
    if (other is! TestParseError) return false;
    if (other.message != message) return false;
    if (other.position != position) return false;
    return true;
  }

  @override
  String toString() {
    return "TestParseError[$position, $message]";
  }
}

enum TestOutcome {
  Pass,
  Failed,
  Crash,
  TestCompilationError,
  CompilationError,
  RuntimeError,
  FrameworkError
}

class TestResult {
  final Test? test;
  final TestOutcome outcome;
  String? message;

  TestResult(this.test, this.outcome);

  @override
  bool operator ==(Object other) {
    if (other is! TestResult) return false;
    if (other.test != test) return false;
    if (other.outcome != outcome) return false;
    if (other.message != message) return false;
    return true;
  }

  @override
  String toString() {
    if (message != null) {
      return "TestResult[$outcome, $test, $message]";
    }
    return "TestResult[$outcome, $test]";
  }
}

List<Test> extractTestsFromComment(
    CommentToken comment, String rawString, kernel.Source source) {
  CommentString commentsData = extractComments(comment, rawString);
  final String comments = commentsData.string;
  List<Test> result = [];
  int index = comments.indexOf("DartDocTest(");
  if (index < 0) {
    return result;
  }

  Test scanDartDoc(int scanOffset) {
    final Token firstToken =
        scanRawBytes(utf8.encode(comments.substring(scanOffset)) as Uint8List);
    final ErrorListener listener = new ErrorListener();
    final Parser parser = new Parser(listener,
        useImplicitCreationExpression: useImplicitCreationExpressionInCfe);
    parser.asyncState = AsyncModifier.Async;

    final Token pastErrors = parser.skipErrorTokens(firstToken);
    assert(pastErrors.isIdentifier);
    assert(pastErrors.lexeme == "DartDocTest");

    final Token startParen = pastErrors.next!;
    assert(identical("(", startParen.stringValue));

    // Advance index so we don't parse the same thing again (for error cases).
    index = scanOffset + startParen.charEnd;

    final Token beforeComma = parser.parseExpression(startParen);
    final Token comma = beforeComma.next!;

    if (listener.hasErrors) {
      StringBuffer sb = new StringBuffer();
      int firstPosition = _createParseErrorMessages(
          listener, sb, commentsData, scanOffset, source);
      return new TestParseError(sb.toString(), firstPosition);
    } else if (!identical(",", comma.stringValue)) {
      int position = commentsData.charOffset + scanOffset + comma.charOffset;
      Message message = codes.templateExpectedButGot.withArguments(',');
      return new TestParseError(
        _createParseErrorMessage(source, position, comma, comma, message),
        position,
      );
    }

    Token beforeEndParen = parser.parseExpression(comma);
    Token endParen = beforeEndParen.next!;

    if (listener.hasErrors) {
      StringBuffer sb = new StringBuffer();
      int firstPosition = _createParseErrorMessages(
          listener, sb, commentsData, scanOffset, source);
      return new TestParseError(sb.toString(), firstPosition);
    } else if (!identical(")", endParen.stringValue)) {
      int position = commentsData.charOffset + scanOffset + endParen.charOffset;
      Message message = codes.templateExpectedButGot.withArguments(')');
      return new TestParseError(
        _createParseErrorMessage(source, position, comma, comma, message),
        position,
      );
    }

    // Advance index so we don't parse the same thing again (success case).
    index = scanOffset + endParen.charEnd;

    int startPos = scanOffset + startParen.next!.charOffset;
    int midEndPos = scanOffset + beforeComma.charEnd;
    int midStartPos = scanOffset + comma.next!.charOffset;
    int endPos = scanOffset + beforeEndParen.charEnd;
    return new ExpectTest(
      comments.substring(startPos, midEndPos),
      comments.substring(midStartPos, endPos),
    );
  }

  while (index >= 0) {
    result.add(scanDartDoc(index));
    index = comments.indexOf("DartDocTest(", index);
  }
  return result;
}

int _createParseErrorMessages(ErrorListener listener, StringBuffer sb,
    CommentString commentsData, int scanOffset, kernel.Source source) {
  assert(listener.recoverableErrors.isNotEmpty);
  sb.writeln("Parse error(s):");
  int? firstPosition;
  for (RecoverableError recoverableError in listener.recoverableErrors) {
    final int position = commentsData.charOffset +
        scanOffset +
        recoverableError.startToken.charOffset;
    firstPosition ??= position;
    sb.writeln("");
    sb.write(_createParseErrorMessage(
      source,
      position,
      recoverableError.startToken,
      recoverableError.endToken,
      recoverableError.message,
    ));
  }
  return firstPosition!;
}

String _createParseErrorMessage(kernel.Source source, int position,
    Token startToken, Token endToken, Message message) {
  kernel.Location location = source.getLocation(source.importUri!, position);
  return command_line_reporting.formatErrorMessage(
      source.getTextLine(location.line),
      location,
      endToken.charEnd - startToken.charOffset,
      source.importUri!.toString(),
      message.problemMessage);
}

CommentString extractComments(CommentToken comment, String rawString) {
  List<int> fileCodeUnits = rawString.codeUnits;
  final int charOffset = comment.charOffset;
  int expectedCharOffset = charOffset;
  StringBuffer sb = new StringBuffer();
  CommentToken? commentToken = comment;
  bool commentBlock = false;
  bool commentBlockStar = false;
  while (commentToken != null) {
    if (expectedCharOffset != commentToken.charOffset) {
      // Missing spaces/linebreaks.
      assert(expectedCharOffset < commentToken.offset);
      for (int i = expectedCharOffset; i < commentToken.offset; i++) {
        if (fileCodeUnits[i] == $LF) {
          sb.writeCharCode($LF);
        } else {
          sb.write(" ");
        }
      }
    }
    expectedCharOffset = commentToken.charEnd;
    String data = commentToken.lexeme;
    if (!commentBlock) {
      if (data.startsWith("///")) {
        data = data.substring(3);
        sb.write("   ");
      } else if (data.startsWith("//")) {
        data = data.substring(2);
        sb.write("  ");
      } else if (data.startsWith("/**")) {
        data = data.substring(3);
        commentBlock = true;
        commentBlockStar = true;
        sb.write("   ");
      } else if (data.startsWith("/*")) {
        data = data.substring(2);
        commentBlock = true;
        sb.write("  ");
      }
    }

    if (commentBlock && data.endsWith("*/")) {
      // Remove ending "*/"" as well as "starting" "*" if in a "/**" block.
      List<int> codeUnits = data.codeUnits;
      bool sawNewlineLast = false;
      for (int i = 0; i < codeUnits.length - 2; i++) {
        int codeUnit = codeUnits[i];
        if (codeUnit == $LF) {
          sb.writeCharCode($LF);
          sawNewlineLast = true;
        } else if (codeUnit <= $SPACE) {
          sb.writeCharCode($SPACE);
        } else if (commentBlockStar && sawNewlineLast && codeUnit == $STAR) {
          sb.writeCharCode($SPACE);
          sawNewlineLast = false;
        } else {
          sawNewlineLast = false;
          sb.writeCharCode(codeUnit);
        }
      }
      sb.write("  ");
      commentBlock = false;
      commentBlockStar = false;
    } else {
      sb.write(data);
    }
    Token? next = commentToken.next;
    commentToken = null;
    if (next is CommentToken) commentToken = next;
  }
  return new CommentString(sb.toString(), charOffset);
}

class CommentString {
  final String string;
  final int charOffset;

  CommentString(this.string, this.charOffset);

  @override
  bool operator ==(Object other) {
    if (other is! CommentString) return false;
    if (other.string != string) return false;
    if (other.charOffset != charOffset) return false;
    return true;
  }

  @override
  String toString() {
    return "CommentString[$charOffset, $string]";
  }
}

class ErrorListener extends NullListener {
  List<RecoverableError> recoverableErrors = [];

  @override
  void handleRecoverableError(
      Message message, Token startToken, Token endToken) {
    super.handleRecoverableError(message, startToken, endToken);
    recoverableErrors.add(new RecoverableError(message, startToken, endToken));
  }
}

class RecoverableError {
  final Message message;
  final Token startToken;
  final Token endToken;

  RecoverableError(this.message, this.startToken, this.endToken);
}

class DocTestIncrementalCompiler extends IncrementalCompiler {
  static final Uri dartDocTestUri =
      new Uri(scheme: "dartdoctest", path: "tester");
  DocTestIncrementalCompiler(CompilerContext context) : super(context);

  @override
  bool dontReissueLibraryProblemsFor(Uri? uri) {
    return super.dontReissueLibraryProblemsFor(uri) || uri == dartDocTestUri;
  }

  @override
  IncrementalKernelTarget createIncrementalKernelTarget(
      FileSystem fileSystem,
      bool includeComments,
      DillTarget dillTarget,
      UriTranslator uriTranslator) {
    return new DocTestIncrementalKernelTarget(
        this, fileSystem, includeComments, dillTarget, uriTranslator);
  }

  LibraryBuilder? _dartDocTestLibraryBuilder;
  String? _dartDocTestCode;

  Future<kernel.Component> compileDartDocTestLibrary(
      String dartDocTestCode, Uri libraryUri) async {
    assert(dillLoadedData != null && userCode != null);

    return await context.runInContext((_) async {
      LibraryBuilder libraryBuilder = userCode!.loader
          .read(libraryUri, -1, accessor: userCode!.loader.first);

      userCode!.loader.resetSeenMessages();

      _dartDocTestLibraryBuilder = libraryBuilder;
      _dartDocTestCode = dartDocTestCode;

      invalidate(dartDocTestUri);
      kernel.Component result = await computeDelta(
          entryPoints: [dartDocTestUri], fullComponent: true);
      _dartDocTestLibraryBuilder = null;
      _dartDocTestCode = null;

      userCode!.uriToSource.remove(dartDocTestUri);
      userCode!.loader.sourceBytes.remove(dartDocTestUri);

      return result;
    });
  }

  SourceLibraryBuilder createDartDocTestLibrary(LibraryBuilder libraryBuilder) {
    SourceLibraryBuilder dartDocTestLibrary = new SourceLibraryBuilder(
      dartDocTestUri,
      dartDocTestUri,
      /*packageUri*/ null,
      new ImplicitLanguageVersion(libraryBuilder.library.languageVersion),
      userCode!.loader,
      null,
      scope: libraryBuilder.scope.createNestedScope("dartdoctest"),
      nameOrigin: libraryBuilder,
    );

    if (libraryBuilder is DillLibraryBuilder) {
      for (kernel.LibraryDependency dependency
          in libraryBuilder.library.dependencies) {
        if (!dependency.isImport) continue;

        List<CombinatorBuilder>? combinators;

        for (kernel.Combinator combinator in dependency.combinators) {
          combinators ??= <CombinatorBuilder>[];

          combinators.add(combinator.isShow
              ? new CombinatorBuilder.show(combinator.names,
                  combinator.fileOffset, libraryBuilder.fileUri)
              : new CombinatorBuilder.hide(combinator.names,
                  combinator.fileOffset, libraryBuilder.fileUri));
        }

        dartDocTestLibrary.addImport(
            null,
            dependency.importedLibraryReference.asLibrary.importUri.toString(),
            null,
            dependency.name,
            combinators,
            dependency.isDeferred,
            -1,
            -1,
            -1,
            -1);
      }

      dartDocTestLibrary.addImport(null, libraryBuilder.importUri.toString(),
          null, null, null, false, -1, -1, -1, -1);

      dartDocTestLibrary.addImportsToScope();
    } else {
      throw "Got ${libraryBuilder.runtimeType}";
    }

    return dartDocTestLibrary;
  }
}

class DocTestIncrementalKernelTarget extends IncrementalKernelTarget {
  final DocTestIncrementalCompiler compiler;
  DocTestIncrementalKernelTarget(this.compiler, FileSystem fileSystem,
      bool includeComments, DillTarget dillTarget, UriTranslator uriTranslator)
      : super(fileSystem, includeComments, dillTarget, uriTranslator);

  @override
  LibraryBuilder createLibraryBuilder(
      Uri uri,
      Uri fileUri,
      Uri? packageUri,
      LanguageVersion packageLanguageVersion,
      SourceLibraryBuilder? origin,
      kernel.Library? referencesFrom,
      bool? referenceIsPartOwner) {
    if (uri == DocTestIncrementalCompiler.dartDocTestUri) {
      HybridFileSystem hfs = compiler.userCode!.fileSystem as HybridFileSystem;
      MemoryFileSystem fs = hfs.memory;
      fs
          .entityForUri(DocTestIncrementalCompiler.dartDocTestUri)
          .writeAsStringSync(compiler._dartDocTestCode!);
      return compiler
          .createDartDocTestLibrary(compiler._dartDocTestLibraryBuilder!);
    }
    return super.createLibraryBuilder(uri, fileUri, packageUri,
        packageLanguageVersion, origin, referencesFrom, referenceIsPartOwner);
  }
}
