// Copyright (c) 2026, 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 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer_testing/utilities/extensions/diagnostic_code.dart';

/// Returns [content] with canonical diagnostic expectation markers.
///
/// Existing diagnostic expectation marker lines are removed before the new
/// markers are inserted, so [content] can be either unmarked or already marked.
String updateExpectedDiagnostics({
  required String content,
  required List<Diagnostic> actualDiagnostics,
}) {
  return _ExpectedDiagnosticsUpdater(content).update(actualDiagnostics);
}

final class _ExpectedDiagnosticsUpdater {
  final List<_Line> lines;
  final LineInfo lineInfo;
  final Map<int, List<_GeneratedMarker>> markersByLine = {};

  int nextMarkerIndex = 0;
  int nextContextId = 1;

  _ExpectedDiagnosticsUpdater(String content)
    : lines = _Line.parse(content),
      lineInfo = LineInfo.fromContent(content);

  String update(List<Diagnostic> actualDiagnostics) {
    _generateMarkers(actualDiagnostics);
    return _writeContent();
  }

  void _addMarker(int lineNumber, _GeneratedMarker marker) {
    markersByLine.putIfAbsent(lineNumber, () => []).add(marker);
  }

  /// Builds a caret marker line for a one-based [column] and [length].
  String _caretLine(int column, int length) {
    return '//${' ' * (column - 3)}${'^' * length}';
  }

  void _generateDiagnosticMarkers(Diagnostic diagnostic) {
    var contextRefs = <int>[];
    for (var contextMessage in diagnostic.contextMessages) {
      if (contextMessage.filePath != diagnostic.problemMessage.filePath) {
        // TODO(scheglov): Support generating expectations for context
        // messages in other files.
        throw StateError(
          'Cannot generate a diagnostic expectation with a context message '
          'in another file.',
        );
      }

      var id = nextContextId++;
      contextRefs.add(id);
      var location = _markerLocation(
        offset: contextMessage.offset,
        length: contextMessage.length,
      );
      var line = lines[location.lineNumber - 1];
      var presentation = _markerPresentation(
        line,
        column: location.column,
        length: contextMessage.length,
      );
      _addMarker(
        location.lineNumber,
        _GeneratedMarker.context(
          offset: contextMessage.offset,
          index: nextMarkerIndex++,
          id: id,
          column: location.column,
          length: contextMessage.length,
          caretLength: presentation.caretLength,
          includeExplicitLocation: presentation.includeExplicitLocation,
          message: contextMessage.messageText(includeUrl: false),
        ),
      );
    }

    var location = _markerLocation(
      offset: diagnostic.offset,
      length: diagnostic.length,
    );
    var line = lines[location.lineNumber - 1];
    var presentation = _markerPresentation(
      line,
      column: location.column,
      length: diagnostic.length,
    );
    _addMarker(
      location.lineNumber,
      _GeneratedMarker.diagnostic(
        offset: diagnostic.offset,
        index: nextMarkerIndex++,
        constantName: diagnostic.diagnosticCode.constantName,
        column: location.column,
        length: diagnostic.length,
        caretLength: presentation.caretLength,
        includeExplicitLocation: presentation.includeExplicitLocation,
        contextRefs: contextRefs,
        message: diagnostic.problemMessage.messageText(includeUrl: false),
      ),
    );
  }

  void _generateMarkers(List<Diagnostic> actualDiagnostics) {
    var sortedDiagnostics = actualDiagnostics.toList()
      ..sort((first, second) => first.offset.compareTo(second.offset));
    for (var diagnostic in sortedDiagnostics) {
      _generateDiagnosticMarkers(diagnostic);
    }
  }

  /// Returns where a generated marker should be written for an actual range.
  ///
  /// For a normal diagnostic range, the marker belongs on the line reported by
  /// [LineInfo]. For a zero-length diagnostic, the diagnostic is often an
  /// insertion point rather than a source span. If the input is already
  /// marked, that insertion point can be pushed into the existing marker
  /// comments, or to the empty line after them, even though the marker should
  /// still be attached to the preceding real source line. In that case, keep
  /// the marker on the source line and express the insertion point as the
  /// column after its last character.
  ({int lineNumber, int column}) _markerLocation({
    required int offset,
    required int length,
  }) {
    var location = lineInfo.getLocation(offset);
    if (length == 0) {
      // Only zero-length diagnostics can legitimately move onto marker-only
      // text from a previous update. A non-zero range on a marker line would
      // describe the marker comment itself, not an insertion point in code.
      var targetLine = _targetLineForMarkerShift(location.lineNumber);
      if (targetLine != null) {
        return (
          lineNumber: targetLine.number,
          column: targetLine.text.length + 1,
        );
      }
    }
    return (lineNumber: location.lineNumber, column: location.columnNumber);
  }

  /// Returns how [column] and [length] should be shown after [line].
  ///
  /// Caret lines start with `//`, so columns 1 and 2 cannot be represented. A
  /// zero-length range may still use a one-character caret as a visual anchor,
  /// but must keep explicit `[column ...][length 0]` metadata.
  ({int? caretLength, bool includeExplicitLocation}) _markerPresentation(
    _Line line, {
    required int column,
    required int length,
  }) {
    int? caretLength;
    if (column > 2) {
      if (length == 0 && column <= line.text.length + 1) {
        caretLength = 1;
      } else if (length > 0 && column + length - 1 <= line.text.length) {
        caretLength = length;
      }
    }

    return (
      caretLength: caretLength,
      includeExplicitLocation: caretLength != length,
    );
  }

  /// Finds the real source line that owns a shifted zero-length marker.
  ///
  /// The updater accepts both clean source and source that already contains
  /// diagnostic expectation comments. Existing marker comments are removed when
  /// the new content is written, but actual diagnostics are computed before
  /// that removal. This matters for zero-length diagnostics near the end of a
  /// line or file: after a previous update, the analyzer may report the same
  /// insertion point as being on a marker line, or on the empty line
  /// immediately following marker lines.
  ///
  /// This method recognizes only those shifted positions. If [lineNumber]
  /// points at ordinary source text, or at an empty line that is not directly
  /// after a marker, there is nothing to repair and `null` is returned.
  /// Otherwise the search walks backward over marker lines and returns the
  /// nearest preceding non-marker line, which is where the regenerated marker
  /// should be attached.
  _Line? _targetLineForMarkerShift(int lineNumber) {
    if (lineNumber < 1 || lineNumber > lines.length) {
      return null;
    }

    var line = lines[lineNumber - 1];
    if (!_LineMarker.isMarker(line)) {
      // A non-marker line normally owns the reported offset. The one exception
      // is the synthetic empty line after existing markers, which can be where
      // EOF-style zero-length diagnostics land.
      var previousLine = lineNumber > 1 ? lines[lineNumber - 2] : null;
      if (line.text.isNotEmpty ||
          previousLine == null ||
          !_LineMarker.isMarker(previousLine)) {
        return null;
      }
    }

    // The reported line is either a marker line or the empty line just after
    // marker lines. Walk back to the line these markers annotate.
    for (var index = lineNumber - 2; index >= 0; index--) {
      var previousLine = lines[index];
      if (!_LineMarker.isMarker(previousLine)) {
        return previousLine;
      }
    }
    return null;
  }

  String _writeContent() {
    var buffer = StringBuffer();
    var isFirstLine = true;
    for (var line in lines) {
      if (_LineMarker.isMarker(line)) {
        continue;
      }

      if (isFirstLine) {
        isFirstLine = false;
      } else {
        buffer.writeln();
      }
      buffer.write(line.text);

      var markers = markersByLine[line.number];
      if (markers != null) {
        markers.sort(_GeneratedMarker.compare);
        ({int column, int length})? currentCaret;
        for (var marker in markers) {
          if (marker.caretLength case var caretLength?) {
            var markerCaret = (column: marker.column, length: caretLength);
            if (markerCaret != currentCaret) {
              buffer.writeln();
              buffer.write(_caretLine(marker.column, caretLength));
              currentCaret = markerCaret;
            }
          }
          buffer.writeln();
          buffer.write(marker.expectationText);
        }
      }
    }
    return buffer.toString();
  }
}

/// Generated expectation marker text for one diagnostic or context message.
final class _GeneratedMarker {
  /// The zero-based offset of the diagnostic or context message being marked.
  final int offset;

  /// The marker kind, used as a stable secondary sort key.
  final _GeneratedMarkerKind kind;

  /// The order in which this marker was generated.
  final int index;

  /// The one-based column of the diagnostic or context message range.
  final int column;

  /// The length of the visual caret marker, or `null` if none should be shown.
  ///
  /// For zero-length diagnostics, a one-character caret is useful as a visual
  /// anchor, but the exact `[column ...][length 0]` metadata must still be
  /// emitted.
  final int? caretLength;

  /// The expectation comment inserted after the target line.
  final String expectationText;

  /// Creates a marker for a diagnostic context message.
  factory _GeneratedMarker.context({
    required int offset,
    required int index,
    required int id,
    required int column,
    required int length,
    required int? caretLength,
    required bool includeExplicitLocation,
    required String message,
  }) {
    var buffer = StringBuffer();
    buffer.write('// [context $id]');
    if (includeExplicitLocation) {
      buffer.write('[column $column][length $length]');
    }
    buffer.write(' $message');

    return _GeneratedMarker._(
      offset: offset,
      kind: _GeneratedMarkerKind.context,
      index: index,
      column: column,
      caretLength: caretLength,
      expectationText: buffer.toString(),
    );
  }

  /// Creates a marker for a diagnostic.
  factory _GeneratedMarker.diagnostic({
    required int offset,
    required int index,
    required String constantName,
    required int column,
    required int length,
    required int? caretLength,
    required bool includeExplicitLocation,
    required List<int> contextRefs,
    required String message,
  }) {
    var buffer = StringBuffer();
    buffer.write('// [$constantName]');
    if (includeExplicitLocation) {
      buffer.write('[column $column][length $length]');
    }
    for (var id in contextRefs) {
      buffer.write('[context $id]');
    }
    buffer.write(' $message');

    return _GeneratedMarker._(
      offset: offset,
      kind: _GeneratedMarkerKind.diagnostic,
      index: index,
      column: column,
      caretLength: caretLength,
      expectationText: buffer.toString(),
    );
  }

  _GeneratedMarker._({
    required this.offset,
    required this.kind,
    required this.index,
    required this.column,
    required this.caretLength,
    required this.expectationText,
  });

  /// Orders generated markers in the order they should appear after a line.
  static int compare(_GeneratedMarker first, _GeneratedMarker second) {
    var offsetResult = first.offset.compareTo(second.offset);
    if (offsetResult != 0) {
      return offsetResult;
    }
    var kindResult = first.kind.index.compareTo(second.kind.index);
    if (kindResult != 0) {
      return kindResult;
    }
    return first.index.compareTo(second.index);
  }
}

enum _GeneratedMarkerKind { context, diagnostic }

/// A line of text in the input content.
final class _Line {
  /// The one-based line number in the input content.
  final int number;

  /// The line text without the trailing newline characters.
  final String text;

  _Line({required this.number, required this.text});

  /// Splits [content] into lines while preserving each line's offset.
  ///
  /// Lines may end with `\r`, `\n`, or `\r\n`. The newline characters are not
  /// included in [text], but they still contribute to offsets in [content].
  static List<_Line> parse(String content) {
    var result = <_Line>[];
    var lineStart = 0;
    var lineNumber = 1;

    for (var index = 0; index < content.length; index++) {
      var codeUnit = content.codeUnitAt(index);
      if (codeUnit == 0x0D || codeUnit == 0x0A) {
        result.add(
          _Line(
            number: lineNumber++,
            text: content.substring(lineStart, index),
          ),
        );

        // Consume the `\n` in a `\r\n` line break.
        if (codeUnit == 0x0D &&
            index + 1 < content.length &&
            content.codeUnitAt(index + 1) == 0x0A) {
          index++;
        }
        lineStart = index + 1;
      }
    }

    result.add(_Line(number: lineNumber, text: content.substring(lineStart)));
    return result;
  }
}

abstract final class _LineMarker {
  /// Matches a caret marker line such as `//   ^^^`.
  static final _caretPattern = RegExp(r'^[ \t]*//[ \t]*\^+[ \t]*$');

  /// Matches generated expectation comments for diagnostics and contexts.
  ///
  /// The updater only needs to recognize lines to remove before regeneration.
  /// It intentionally does not validate the full marker syntax.
  static final _expectationPattern = RegExp(
    r'^[ \t]*//[ \t]*\[(?:diag\.[A-Za-z_][A-Za-z0-9_]*|context[ \t]+[0-9]+)\]',
  );

  static bool isMarker(_Line line) {
    return _caretPattern.hasMatch(line.text) ||
        _expectationPattern.hasMatch(line.text);
  }
}
