// 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 'test_file.dart';

/// Matches leading indentation in a string.
final _indentationRegExp = RegExp(r"^(\s*)");

/// Matches a line that contains only a line comment.
final _lineCommentRegExp = RegExp(r"^\s*//");

/// Removes existing static error marker comments in [source] and adds markers
/// for the given [errors].
///
/// If [removeAnalyzer] is `false`, then existing analyzer errors in [source]
/// are preserved. Likewise for [removeCfe] and CFE errors.
String updateErrorExpectations(String source, List<StaticError> errors,
    {bool removeAnalyzer, bool removeCfe}) {
  removeAnalyzer ??= true;
  removeCfe ??= true;

  var existingErrors = ErrorExpectationParser.parse(source);
  var lines = source.split("\n");

  // Keep track of the indentation on any existing expectation markers. If
  // found, it will try to preserve that indentation.
  var indentation = <int, int>{};

  // Remove existing markers that should be removed.
  var preservedErrors = <StaticError>[];
  for (var error in existingErrors) {
    for (var i = error.markerStartLine; i <= error.markerEndLine; i++) {
      indentation[i] = _countIndentation(lines[i]);

      // Null the line instead of removing it so that line numbers in the
      // reported errors are still correct.
      lines[i] = null;
    }

    // Re-add errors for the portions we intend to preserve.
    var keepCode = !removeAnalyzer && error.code != null;
    var keepMessage = !removeCfe && error.message != null;

    if (keepCode || keepMessage) {
      preservedErrors.add(StaticError(
          line: error.line,
          column: error.column,
          length: error.length,
          code: keepCode ? error.code : null,
          message: keepMessage ? error.message : null));
    }
  }

  // Merge the new errors with the preserved ones.
  errors = StaticError.simplify([...errors, ...preservedErrors]);

  var errorMap = <int, List<StaticError>>{};
  for (var error in errors) {
    // -1 to translate from one-based to zero-based index.
    errorMap.putIfAbsent(error.line - 1, () => []).add(error);
  }

  // If there are multiple errors on the same line, order them
  // deterministically.
  for (var errorList in errorMap.values) {
    errorList.sort();
  }

  var previousIndent = 0;
  var result = <String>[];
  for (var i = 0; i < lines.length; i++) {
    // Keep the code.
    if (lines[i] != null) {
      result.add(lines[i]);
      previousIndent = _countIndentation(lines[i]);
    }

    // Add expectations for any errors reported on this line.
    var errorsHere = errorMap[i];
    if (errorsHere == null) continue;
    for (var error in errorsHere) {
      // Try to indent the line nicely to match either the existing expectation
      // that is being regenerated, or, barring that, the previous line of code.
      var indent = indentation[i + 1] ?? previousIndent;

      // If the error is to the left of the indent and the "//", sacrifice the
      // indentation.
      if (error.column - 1 < indent + 2) indent = 0;

      var comment = (" " * indent) + "//";

      // If the error can't fit in a line comment or doesn't have a length, use
      // an explicit location.
      if (error.length == null) {
        result.add("$comment [error line ${error.line}, column "
            "${error.column}]");
      } else if (error.column <= 2) {
        result.add("$comment [error line ${error.line}, column "
            "${error.column}, length ${error.length}]");
      } else {
        var spacing = " " * (error.column - 1 - 2 - indent);
        // A CFE-only error may not have a length, so treat it as length 1.
        var carets = "^" * (error.length ?? 1);
        result.add("$comment$spacing$carets");
      }

      if (error.code != null) {
        result.add("$comment [analyzer] ${error.code}");
      }

      if (error.message != null) {
        var errorLines = error.message.split("\n");
        result.add("$comment [cfe] ${errorLines[0]}");
        for (var errorLine in errorLines.skip(1)) {
          result.add("$comment $errorLine");
        }

        // If the very next line in the source is a line comment, it would
        // become part of the inserted message. To prevent that, insert a blank
        // line.
        if (i < lines.length - 1 &&
            lines[i + 1] != null &&
            _lineCommentRegExp.hasMatch(lines[i + 1])) {
          result.add("");
        }
      }
    }
  }

  return result.join("\n");
}

/// Returns the number of characters of leading spaces in [line].
int _countIndentation(String line) {
  var match = _indentationRegExp.firstMatch(line);
  return match.group(1).length;
}
