// Copyright (c) 2019, 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:convert' show jsonDecode;

import 'dart:io' show File;

import 'dart:typed_data' show Uint8List;

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

import 'package:front_end/src/fasta/messages.dart' show Message;
import 'package:front_end/src/fasta/source/diet_parser.dart'
    show useImplicitCreationExpressionInCfe;

import 'package:front_end/src/fasta/util/direct_parser_ast.dart' show getAST;

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

import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
    show ErrorToken, ScannerConfiguration, Token, Utf8BytesScanner;

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

import 'package:front_end/src/fasta/source/stack_listener_impl.dart'
    show offsetForToken;

import 'package:front_end/src/fasta/util/direct_parser_ast_helper.dart'
    show DirectParserASTContent;

import 'package:kernel/ast.dart';

import 'package:testing/testing.dart'
    show
        Chain,
        ChainContext,
        ExpectationSet,
        Result,
        Step,
        TestDescription,
        runMe;

import 'fasta/testing/suite.dart' show UPDATE_EXPECTATIONS;
import 'utils/kernel_chain.dart' show MatchContext;

import 'parser_test_listener.dart' show ParserTestListener;

import 'parser_test_parser.dart' show TestParser;

import 'testing_utils.dart' show checkEnvironment;

const String EXPECTATIONS = '''
[
  {
    "name": "ExpectationFileMismatch",
    "group": "Fail"
  },
  {
    "name": "ExpectationFileMissing",
    "group": "Fail"
  }
]
''';

main([List<String> arguments = const []]) =>
    runMe(arguments, createContext, configurationPath: "../testing.json");

Future<Context> createContext(
    Chain suite, Map<String, String> environment) async {
  const Set<String> knownEnvironmentKeys = {
    "updateExpectations",
    "trace",
    "annotateLines"
  };
  checkEnvironment(environment, knownEnvironmentKeys);

  bool updateExpectations = environment["updateExpectations"] == "true";
  bool trace = environment["trace"] == "true";
  bool annotateLines = environment["annotateLines"] == "true";

  return new Context(suite.name, updateExpectations, trace, annotateLines);
}

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

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

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

class Context extends ChainContext with MatchContext {
  @override
  final bool updateExpectations;

  @override
  String get updateExpectationsOption => '${UPDATE_EXPECTATIONS}=true';

  @override
  bool get canBeFixWithUpdateExpectations => true;

  final bool addTrace;
  final bool annotateLines;
  final String suiteName;

  Context(this.suiteName, this.updateExpectations, this.addTrace,
      this.annotateLines);

  @override
  final List<Step> steps = const <Step>[
    const TokenStep(true, ".scanner.expect"),
    const TokenStep(false, ".parser.expect"),
    const ListenerStep(true),
    const IntertwinedStep(),
  ];

  @override
  final ExpectationSet expectationSet =
      new ExpectationSet.fromJsonList(jsonDecode(EXPECTATIONS));

  // Override special handling of negative tests.
  @override
  Result processTestResult(
      TestDescription description, Result result, bool last) {
    return result;
  }
}

class ContextChecksOnly extends Context {
  ContextChecksOnly(String suiteName) : super(suiteName, false, false, false);

  @override
  final List<Step> steps = const <Step>[
    const ListenerStep(false),
    const DirectParserASTStep(),
  ];

  @override
  final ExpectationSet expectationSet =
      new ExpectationSet.fromJsonList(jsonDecode(EXPECTATIONS));

  // Override special handling of negative tests.
  @override
  Result processTestResult(
      TestDescription description, Result result, bool last) {
    return result;
  }
}

class DirectParserASTStep
    extends Step<TestDescription, TestDescription, Context> {
  const DirectParserASTStep();
  @override
  String get name => "DirectParserAST";
  @override
  Future<Result<TestDescription>> run(
      TestDescription description, Context context) {
    Uri uri = description.uri;
    File f = new File.fromUri(uri);
    List<int> rawBytes = f.readAsBytesSync();
    DirectParserASTContent ast = getAST(rawBytes);
    if (ast.what != "CompilationUnit") {
      throw "Expected a single element for 'CompilationUnit' "
          "but got ${ast.what}";
    }
    return new Future.value(new Result<TestDescription>.pass(description));
  }
}

class ListenerStep extends Step<TestDescription, TestDescription, Context> {
  final bool doExpects;
  const ListenerStep(this.doExpects);

  @override
  String get name => "listener";

  /// Scans the uri, parses it with the test listener and returns it.
  ///
  /// Returns null if scanner doesn't return any Token.
  static ParserTestListenerWithMessageFormatting? doListenerParsing(
      Uri uri, String suiteName, String shortName,
      {bool addTrace: false, bool annotateLines: false}) {
    List<int> lineStarts = <int>[];
    Token firstToken = scanUri(uri, shortName, lineStarts: lineStarts);

    // ignore: unnecessary_null_comparison
    if (firstToken == null) {
      return null;
    }

    File f = new File.fromUri(uri);
    List<int> rawBytes = f.readAsBytesSync();
    Source source = new Source(lineStarts, rawBytes, uri, uri);
    String shortNameId = "${suiteName}/${shortName}";
    ParserTestListenerWithMessageFormatting parserTestListener =
        new ParserTestListenerWithMessageFormatting(
            addTrace, annotateLines, source, shortNameId);
    Parser parser = new Parser(parserTestListener,
        useImplicitCreationExpression: useImplicitCreationExpressionInCfe);
    parser.parseUnit(firstToken);
    return parserTestListener;
  }

  @override
  Future<Result<TestDescription>> run(
      TestDescription description, Context context) {
    Uri uri = description.uri;

    ParserTestListenerWithMessageFormatting? parserTestListener =
        doListenerParsing(
      uri,
      context.suiteName,
      description.shortName,
      addTrace: context.addTrace,
      annotateLines: context.annotateLines,
    );
    if (parserTestListener == null) {
      return Future.value(crash(description, StackTrace.current));
    }

    String errors = "";
    if (parserTestListener.errors.isNotEmpty) {
      errors = "Problems reported:\n\n"
          "${parserTestListener.errors.join("\n\n")}\n\n";
    }

    if (doExpects) {
      return context.match<TestDescription>(
          ".expect", "${errors}${parserTestListener.sb}", uri, description);
    } else {
      return new Future.value(new Result<TestDescription>.pass(description));
    }
  }
}

class IntertwinedStep extends Step<TestDescription, TestDescription, Context> {
  const IntertwinedStep();

  @override
  String get name => "intertwined";

  @override
  Future<Result<TestDescription>> run(
      TestDescription description, Context context) {
    List<int> lineStarts = <int>[];
    Token firstToken =
        scanUri(description.uri, description.shortName, lineStarts: lineStarts);

    // ignore: unnecessary_null_comparison
    if (firstToken == null) {
      return Future.value(crash(description, StackTrace.current));
    }

    File f = new File.fromUri(description.uri);
    List<int> rawBytes = f.readAsBytesSync();
    Source source =
        new Source(lineStarts, rawBytes, description.uri, description.uri);

    ParserTestListenerForIntertwined parserTestListener =
        new ParserTestListenerForIntertwined(
            context.addTrace, context.annotateLines, source);
    TestParser parser = new TestParser(parserTestListener, context.addTrace);
    parserTestListener.parser = parser;
    parser.sb = parserTestListener.sb;
    parser.parseUnit(firstToken);

    return context.match<TestDescription>(
        ".intertwined.expect", "${parser.sb}", description.uri, description);
  }
}

class TokenStep extends Step<TestDescription, TestDescription, Context> {
  final bool onlyScanner;
  final String suffix;

  const TokenStep(this.onlyScanner, this.suffix);

  @override
  String get name => "token";

  @override
  Future<Result<TestDescription>> run(
      TestDescription description, Context context) {
    List<int> lineStarts = <int>[];
    Token firstToken =
        scanUri(description.uri, description.shortName, lineStarts: lineStarts);

    // ignore: unnecessary_null_comparison
    if (firstToken == null) {
      return Future.value(crash(description, StackTrace.current));
    }

    StringBuffer beforeParser = tokenStreamToString(firstToken, lineStarts);
    StringBuffer beforeParserWithTypes =
        tokenStreamToString(firstToken, lineStarts, addTypes: true);
    if (onlyScanner) {
      return context.match<TestDescription>(
          suffix,
          "${beforeParser}\n\n${beforeParserWithTypes}",
          description.uri,
          description);
    }

    ParserTestListener parserTestListener =
        new ParserTestListener(context.addTrace);
    Parser parser = new Parser(parserTestListener,
        useImplicitCreationExpression: useImplicitCreationExpressionInCfe);
    bool parserCrashed = false;
    dynamic parserCrashedE;
    StackTrace? parserCrashedSt;
    try {
      parser.parseUnit(firstToken);
    } catch (e, st) {
      parserCrashed = true;
      parserCrashedE = e;
      parserCrashedSt = st;
    }

    StringBuffer afterParser = tokenStreamToString(firstToken, lineStarts);
    StringBuffer afterParserWithTypes =
        tokenStreamToString(firstToken, lineStarts, addTypes: true);

    bool rewritten =
        beforeParserWithTypes.toString() != afterParserWithTypes.toString();
    String rewrittenString =
        rewritten ? "NOTICE: Stream was rewritten by parser!\n\n" : "";

    Future<Result<TestDescription>> result = context.match<TestDescription>(
        suffix,
        "${rewrittenString}${afterParser}\n\n${afterParserWithTypes}",
        description.uri,
        description);
    return result.then((result) {
      if (parserCrashed) {
        return crash("Parser crashed: $parserCrashedE", parserCrashedSt!);
      } else {
        return result;
      }
    });
  }
}

StringBuffer tokenStreamToString(Token firstToken, List<int> lineStarts,
    {bool addTypes: false}) {
  StringBuffer sb = new StringBuffer();
  Token? token = firstToken;

  Token? process(Token? token, bool errorTokens) {
    bool printed = false;
    int endOfLast = -1;
    int lineStartsIteratorLine = 1;
    Iterator<int> lineStartsIterator = lineStarts.iterator;
    lineStartsIterator.moveNext();
    lineStartsIterator.moveNext();
    lineStartsIteratorLine++;

    Set<Token> seenTokens = new Set<Token>.identity();
    while (token != null) {
      if (errorTokens && token is! ErrorToken) return token;
      if (!errorTokens && token is ErrorToken) {
        if (token == token.next) break;
        token = token.next;
        continue;
      }

      int prevLine = lineStartsIteratorLine;
      while (token.offset >= lineStartsIterator.current &&
          lineStartsIterator.moveNext()) {
        lineStartsIteratorLine++;
      }
      if (printed &&
          (token.offset > endOfLast || prevLine < lineStartsIteratorLine)) {
        if (prevLine < lineStartsIteratorLine) {
          for (int i = prevLine; i < lineStartsIteratorLine; i++) {
            sb.write("\n");
          }
        } else {
          sb.write(" ");
        }
      }
      if (token is! ErrorToken) {
        sb.write(token.lexeme);
        if (!addTypes && token.lexeme == "" && token is SyntheticStringToken) {
          sb.write("*synthetic*");
        }
      }
      if (addTypes) {
        sb.write("[${token.runtimeType}]");
      }
      printed = true;
      endOfLast = token.end;
      if (token == token.next) break;
      token = token.next;
      if (!seenTokens.add(token!)) {
        // Loop in tokens: Print error and break to avoid infinite loop.
        sb.write("\n\nERROR: Loop in tokens: $token "
            "(${token.runtimeType}, ${token.type}, ${token.offset})) "
            "was seen before "
            "(linking to ${token.next}, ${token.next.runtimeType}, "
            "${token.next!.type}, ${token.next!.offset})!\n\n");
        break;
      }
    }

    return token;
  }

  if (addTypes) {
    token = process(token, true);
  }
  token = process(token, false);

  return sb;
}

Token scanUri(Uri uri, String shortName, {List<int>? lineStarts}) {
  ScannerConfiguration config;

  String firstDir = shortName.split("/")[0];
  if (firstDir == "non-nnbd") {
    config = scannerConfigurationNonNNBD;
  } else if (firstDir == "no-triple-shift") {
    config = scannerConfigurationNonTripleShift;
  } else {
    config = scannerConfiguration;
  }

  File f = new File.fromUri(uri);
  List<int> rawBytes = f.readAsBytesSync();

  return scanRawBytes(rawBytes, config, lineStarts);
}

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

  Utf8BytesScanner scanner =
      new Utf8BytesScanner(bytes, includeComments: true, configuration: config);
  Token firstToken = scanner.tokenize();
  if (lineStarts != null) {
    lineStarts.addAll(scanner.lineStarts);
  }
  return firstToken;
}

class ParserTestListenerWithMessageFormatting extends ParserTestListener {
  final bool annotateLines;
  final Source? source;
  final String? shortName;
  final List<String> errors = <String>[];
  Location? latestSeenLocation;

  ParserTestListenerWithMessageFormatting(
      bool trace, this.annotateLines, this.source, this.shortName)
      : super(trace);

  @override
  void doPrint(String s) {
    super.doPrint(s);
    if (!annotateLines) {
      if (s.startsWith("beginCompilationUnit(") ||
          s.startsWith("endCompilationUnit(")) {
        if (indent != 0) {
          throw "Incorrect indents: '$s' (indent = $indent).\n\n"
              "${sb.toString()}";
        }
      } else {
        if (indent <= 0) {
          throw "Incorrect indents: '$s' (indent = $indent).\n\n"
              "${sb.toString()}";
        }
      }
    }
  }

  @override
  void seen(Token? token) {
    if (!annotateLines) return;
    if (token == null) return;
    if (source == null) return;
    if (offsetForToken(token) < 0) return;
    Location location =
        source!.getLocation(source!.fileUri!, offsetForToken(token));
    if (latestSeenLocation == null ||
        location.line > latestSeenLocation!.line) {
      latestSeenLocation = location;
      String? sourceLine = source!.getTextLine(location.line);
      doPrint("");
      doPrint("// Line ${location.line}: $sourceLine");
    }
  }

  @override
  bool checkEof(Token token) {
    bool result = super.checkEof(token);
    if (result) {
      errors.add("WARNING: Reporting at eof --- see below for details.");
    }
    return result;
  }

  @override
  void handleRecoverableError(
      Message message, Token startToken, Token endToken) {
    if (source != null) {
      Location location =
          source!.getLocation(source!.fileUri!, offsetForToken(startToken));
      int length = lengthOfSpan(startToken, endToken);
      if (length <= 0) length = 1;
      errors.add(command_line_reporting.formatErrorMessage(
          source!.getTextLine(location.line),
          location,
          length,
          shortName,
          message.message));
    } else {
      errors.add(message.message);
    }

    super.handleRecoverableError(message, startToken, endToken);
  }
}

class ParserTestListenerForIntertwined
    extends ParserTestListenerWithMessageFormatting {
  late TestParser parser;

  ParserTestListenerForIntertwined(
      bool trace, bool annotateLines, Source source)
      : super(trace, annotateLines, source, null);

  @override
  void doPrint(String s) {
    int prevIndent = super.indent;
    super.indent = parser.indent;
    if (s.trim() == "") {
      super.doPrint("");
    } else {
      super.doPrint("listener: " + s);
    }
    super.indent = prevIndent;
  }
}
