// Copyright (c) 2018, 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:analysis_server/lsp_protocol/protocol.dart';
import 'package:analysis_server/src/lsp/error_or.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
import 'package:analysis_server/src/protocol_server.dart'
    as server
    show SourceEdit;
import 'package:analysis_server/src/utilities/extensions/formatter_options.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/source/source.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
import 'package:dart_style/dart_style.dart' hide TrailingCommas;

/// Checks whether a string contains only characters that are allowed to differ
/// between unformattedformatted code (such as whitespace, commas, semicolons).
final _isValidFormatterChange = RegExp(r'^[\s,;<>]*$').hasMatch;

/// Transforms a sequence of LSP document change events to a sequence of source
/// edits used by analysis plugins.
///
/// Since the translation from line/characters to offsets needs to take previous
/// changes into account, this will also apply the edits to [oldContent].
ErrorOr<({String content, List<plugin.SourceEdit> edits})>
applyAndConvertEditsToServer(
  String oldContent,
  List<TextDocumentContentChangeEvent> changes, {
  bool failureIsCritical = false,
}) {
  var newContent = oldContent;
  var serverEdits = <server.SourceEdit>[];

  for (var change in changes) {
    // Change is a union that may/may not include a range. If no range
    // is provided (t2 of the union) the whole document should be replaced.
    var result = change.map(
      // TextDocumentContentChangeEvent1
      // {range, text}
      (change) {
        var lines = LineInfo.fromContent(newContent);
        var offsetStart = toOffset(
          lines,
          change.range.start,
          failureIsCritical: failureIsCritical,
        );
        var offsetEnd = toOffset(
          lines,
          change.range.end,
          failureIsCritical: failureIsCritical,
        );
        if (offsetStart.isError) {
          return failure(offsetStart);
        }
        if (offsetEnd.isError) {
          return failure(offsetEnd);
        }
        (offsetStart, offsetEnd).ifResults((offsetStart, offsetEnd) {
          newContent = newContent.replaceRange(
            offsetStart,
            offsetEnd,
            change.text,
          );
          serverEdits.add(
            server.SourceEdit(
              offsetStart,
              offsetEnd - offsetStart,
              change.text,
            ),
          );
        });
      },
      // TextDocumentContentChangeEvent2
      // {text}
      (change) {
        serverEdits
          ..clear()
          ..add(server.SourceEdit(0, newContent.length, change.text));
        newContent = change.text;
      },
    );
    // If any change fails, immediately return the error.
    if (result != null && result.isError) {
      return failure(result);
    }
  }
  return ErrorOr.success((content: newContent, edits: serverEdits));
}

/// Generates a list of [TextEdit]s to format the code for [result].
///
/// [defaultPageWidth] will be used as the default page width if [result] does
/// not have an analysis_options file that defines a page width.
///
/// If [range] is provided, only edits that intersect with this range will be
/// returned.
ErrorOr<List<TextEdit>?> generateEditsForFormatting(
  ParsedUnitResult result, {
  int? defaultPageWidth,
  Range? range,
}) {
  var unformattedSource = result.content;

  var formatterOptions = result.analysisOptions.formatterOptions;
  // The analysis options page width always takes priority over the default from
  // the LSP configuration.
  var effectivePageWidth = formatterOptions.pageWidth ?? defaultPageWidth;
  var effectiveTrailingCommas = formatterOptions.dartStyleTrailingCommas;
  var effectiveLanguageVersion = result.unit.languageVersion.effective;

  var code = SourceCode(unformattedSource);
  SourceCode formattedResult;
  try {
    // Create a new formatter on every request because it may contain state that
    // affects repeated formats.
    // https://github.com/dart-lang/dart_style/issues/1337
    var formatter = DartFormatter(
      pageWidth: effectivePageWidth,
      trailingCommas: effectiveTrailingCommas,
      languageVersion: effectiveLanguageVersion,
    );
    formattedResult = formatter.formatSource(code);
  } on FormatterException {
    // If the document fails to parse, just return no edits to avoid the
    // use seeing edits on every save with invalid code (if LSP gains the
    // ability to pass a context to know if the format was manually invoked
    // we may wish to change this to return an error for that case).
    return success(null);
  }
  var formattedSource = formattedResult.text;

  if (formattedSource == unformattedSource) {
    return success(null);
  }

  return generateMinimalEdits(result, formattedSource, range: range);
}

List<TextEdit> generateFullEdit(
  LineInfo lineInfo,
  String unformattedSource,
  String formattedSource,
) {
  var end = lineInfo.getLocation(unformattedSource.length);
  return [
    TextEdit(
      range: Range(
        start: Position(line: 0, character: 0),
        end: toPosition(end),
      ),
      newText: formattedSource,
    ),
  ];
}

/// Generates edits that modify the minimum amount of code (if only whitespace,
/// commas and comments) to change the source of [result] to [formatted].
///
/// This allows editors to more easily track important locations (such as
/// breakpoints) without needing to do their own diffing.
///
/// If [range] is supplied, only edits that fall entirely inside this range will
/// be included in the results.
ErrorOr<List<TextEdit>> generateMinimalEdits(
  ParsedUnitResult result,
  String formatted, {
  Range? range,
}) {
  var unformatted = result.content;
  var lineInfo = result.lineInfo;
  var rangeStart =
      range != null ? toOffset(lineInfo, range.start) : success(null);
  var rangeEnd = range != null ? toOffset(lineInfo, range.end) : success(null);

  return (rangeStart, rangeEnd).mapResultsSync((rangeStart, rangeEnd) {
    var computer = _MinimalEditComputer(
      result: result,
      lineInfo: lineInfo,
      unformatted: unformatted,
      formatted: formatted,
      rangeStart: rangeStart,
      rangeEnd: rangeEnd,
    );
    var edits = computer.computeMinimalEdits();
    return success(edits);
  });
}

enum ChangeAnnotations {
  /// Do not include change annotations.
  none,

  /// Include change annotations but do not require a user to confirm changes.
  include,

  /// Include change annotations and require the user to confirm changes.
  requireConfirmation,
}

/// Helper class that bundles up all information required when converting server
/// SourceEdits into LSP-compatible WorkspaceEdits.
class FileEditInformation {
  final OptionalVersionedTextDocumentIdentifier doc;
  final LineInfo lineInfo;

  /// A list of edits to be made to the file.
  ///
  /// These edits must be sorted using servers rules (as in `SourceFileEdit`s).
  ///
  /// Server works with edits that can be applied sequentially to a [String]. This
  /// means inserts at the same offset are in the reverse order. For LSP, all
  /// offsets relate to the original document and inserts with the same offset
  /// appear in the order they will appear in the final document.
  final List<server.SourceEdit> edits;

  final bool newFile;

  /// The selection offset, relative to the edit.
  final int? selectionOffsetRelative;
  final int? selectionLength;

  FileEditInformation(
    this.doc,
    this.lineInfo,
    this.edits, {
    required this.newFile,
    this.selectionOffsetRelative,
    this.selectionLength,
  });
}

/// Computes minimal edits to translate a set of parseable source code into
/// another (usually produced by the formatter).
class _MinimalEditComputer {
  // A set of tokens that the formatter may add or remove, which we will
  // allow and not abort for.
  static const allowedAddOrRemovedTokens = {
    TokenType.COMMA,
    TokenType.SEMICOLON,
  };

  // A set of tokens that the formatter may alter the lexem for but must still
  // match types.
  static const allowedLexemeDifferences = {
    // Comments may have trailing spaces removed from lines.
    TokenType.MULTI_LINE_COMMENT,
    TokenType.SINGLE_LINE_COMMENT,
  };

  // A map of tokens that are allowed to be substituted as a result of
  // format changes and the set of possible sequences they may be replaced
  // with.
  static const allowedSubstitutions = {
    TokenType.GT_GT_GT: {
      [TokenType.GT, TokenType.GT, TokenType.GT],
      [TokenType.GT, TokenType.GT_GT],
      [TokenType.GT_GT, TokenType.GT],
    },
    TokenType.GT_GT: {
      [TokenType.GT, TokenType.GT],
    },
    TokenType.LT_LT: {
      [TokenType.LT, TokenType.LT],
    },
    TokenType.INDEX: {
      [TokenType.OPEN_SQUARE_BRACKET, TokenType.CLOSE_SQUARE_BRACKET],
    },
  };

  final LineInfo _lineInfo;
  final String _unformatted;
  final String _formatted;
  final int? _rangeStart;

  final int? _rangeEnd;
  final Token? _parsedUnformatted;

  final Token? _parsedFormatted;

  /// The edits being built.
  final _edits = <TextEdit>[];

  _MinimalEditComputer({
    required ParsedUnitResult result,
    required LineInfo lineInfo,
    required String unformatted,
    required String formatted,
    required int? rangeStart,
    required int? rangeEnd,
  }) : _lineInfo = lineInfo,
       _unformatted = unformatted,
       _formatted = formatted,
       _rangeStart = rangeStart,
       _rangeEnd = rangeEnd,
       _parsedUnformatted = _parse(unformatted, result.unit.featureSet),
       _parsedFormatted = _parse(formatted, result.unit.featureSet);

  /// Compute the edits.
  ///
  /// If for any reason edits cannot be computed, then:
  ///
  /// - If a range was specified, no edits will be returned.
  /// - If no range was specified, a single edit for the entire document will be
  ///   returned.
  List<TextEdit> computeMinimalEdits() {
    if (_edits.isNotEmpty) {
      throw StateError('computeMinimalEdits may only used once per instance.');
    }

    // It shouldn't be the case that we can't parse the code but if it happens
    // fall back to a full replacement rather than fail.
    if (_parsedFormatted == null || _parsedUnformatted == null) {
      return generateFullEdit(_lineInfo, _unformatted, _formatted);
    }

    var unformattedTokens = _iterateAllTokens(_parsedUnformatted).iterator;
    var formattedTokens = _iterateAllTokens(_parsedFormatted).iterator;

    var unformattedOffset = 0;
    var formattedOffset = 0;

    // Walk through the token streams computing edits for the differences.
    bool unformattedHasMore, formattedHasMore;
    while ((unformattedHasMore =
            unformattedTokens.moveNext()) & // Don't short-circuit.
        (formattedHasMore = formattedTokens.moveNext())) {
      var unformattedToken = unformattedTokens.current;
      var formattedToken = formattedTokens.current;

      // Compute the ranges from each side that that we will produce an edit for.
      // This is usually just the whitespace from each side (the range between the
      // end of the previous token and the start of the current), but in the case
      // of commas will be expanded to include the commas (and then the following
      // whitespace).
      var unformattedStart = unformattedOffset;
      var unformattedEnd = unformattedToken.offset;
      var formattedStart = formattedOffset;
      var formattedEnd = formattedToken.offset;
      var allowAnyContentDifferences = false;

      /// Helper to advance the formatted stream by [count] tokens if it is not
      /// at the end.
      void advanceFormatted([int count = 1]) {
        // Don't use `formattedToken.next?.offset`, that would skip comments.
        formattedEnd = formattedToken.end;
        for (int i = 0; i < count; i++) {
          if (formattedHasMore = formattedTokens.moveNext()) {
            formattedToken = formattedTokens.current;
            formattedEnd = formattedToken.offset;
          }
        }
      }

      /// Helper to advance the unformatted stream by [count] tokens if it is
      /// not at the end.
      void advanceUnformatted([int count = 1]) {
        // Don't use `unformattedToken.next?.offset`, that would skip comments.
        unformattedEnd = unformattedToken.end;
        for (int i = 0; i < count; i++) {
          if (unformattedHasMore = unformattedTokens.moveNext()) {
            unformattedToken = unformattedTokens.current;
            unformattedEnd = unformattedToken.offset;
          }
        }
      }

      // We may need to advance multiple times if multiple allowed tokens are
      // added/removed consecutively.
      while (unformattedHasMore && formattedHasMore) {
        var sameTokenTypes = formattedToken.type == unformattedToken.type;

        // Handle differences allowed when tokens are different types.
        if (!sameTokenTypes) {
          // The formatter added an allowed token, advance over it.
          if (_isAllowedOptional(formattedToken)) {
            advanceFormatted();
            continue;
          }

          // The formatter removed an allowed token, advance over it.
          if (_isAllowedOptional(unformattedToken)) {
            advanceUnformatted();
            continue;
          }

          // The formatter substituted `unformattedToken` for some other tokens
          // starting at `formattedToken`.
          if (_substitutes(unformattedToken, formattedToken) case var num?) {
            advanceUnformatted();
            advanceFormatted(num);
            continue;
          }

          // The formatter collapsed tokens in `unformattedToken` for a new
          // `formattedToken`. This is the opposite of the case above.
          if (_substitutes(formattedToken, unformattedToken) case var num?) {
            advanceFormatted();
            advanceUnformatted(num);
            continue;
          }
        }

        // Handle differences allowed when tokens are the same type.
        if (sameTokenTypes) {
          // The formatter made a change to the lexeme of a token type we allow.
          if (allowedLexemeDifferences.contains(unformattedToken.type) &&
              unformattedToken.lexeme != formattedToken.lexeme) {
            advanceUnformatted();
            advanceFormatted();
            allowAnyContentDifferences = true;
            continue;
          }
        }

        // If we didn't hit any `continue` above to restart the loop, then we
        // are done.
        break;
      }

      if (unformattedToken.lexeme != formattedToken.lexeme) {
        // If the token lexemes do not match, there is a difference in the
        // parsed token streams (this should not ordinarily happen) so use the
        // fallback.
        return _generateFallback();
      }

      // Add edits for the computed ranges.
      _addEditFor(
        unformattedStart,
        unformattedEnd,
        formattedStart,
        formattedEnd,
        allowAnyContentDifferences: allowAnyContentDifferences,
      );

      // And move the pointers along to after these tokens.
      unformattedOffset = unformattedToken.end;
      formattedOffset = formattedToken.end;

      // When range formatting, if we've processed a token that ends after the
      // range then there can't be any more relevant edits and we can return early.
      if (_rangeEnd != null && unformattedOffset > _rangeEnd) {
        return _edits;
      }
    }

    // If we got here and either of the streams still have tokens, something
    // did not match so use the fallback.
    if (unformattedHasMore || formattedHasMore) {
      return _generateFallback();
    }

    // Finally, handle any whitespace that was after the last token.
    _addEditFor(
      unformattedOffset,
      _unformatted.length,
      formattedOffset,
      _formatted.length,
    );

    return _edits;
  }

  /// Helper for comparing whitespace and appending an edit.
  void _addEditFor(
    int unformattedStart,
    int unformattedEnd,
    int formattedStart,
    int formattedEnd, {
    bool allowAnyContentDifferences = false,
  }) {
    var unformattedWhitespace = _unformatted.substring(
      unformattedStart,
      unformattedEnd,
    );
    var formattedWhitespace = _formatted.substring(
      formattedStart,
      formattedEnd,
    );

    if (_rangeStart != null && _rangeEnd != null) {
      // If this change crosses over the start of the requested range,
      // discarding the change may result in leading whitespace of the next line
      // not being formatted correctly.
      //
      // To handle this, if both unformatted/formatted contain at least one
      // newline, split this change into two around the last newline so that the
      // final part (likely leading whitespace) can be included without
      // including the whole change. This cannot be done if the newline is at
      // the end of the source whitespace though, as this would create a split
      // where the first part is the same and the second part is empty,
      // resulting in an infinite loop/stack overflow.
      //
      // Without this, functionality like VS Code's "format modified lines"
      // (which uses Git status to know which lines are edited) may appear to
      // fail to format the first newly added line in a range.
      if (unformattedStart < _rangeStart &&
          unformattedEnd > _rangeStart &&
          unformattedWhitespace.contains('\n') &&
          formattedWhitespace.contains('\n') &&
          !unformattedWhitespace.endsWith('\n')) {
        // Find the offsets of the character after the last newlines.
        var unformattedOffset = unformattedWhitespace.lastIndexOf('\n') + 1;
        var formattedOffset = formattedWhitespace.lastIndexOf('\n') + 1;
        // Call us again for the leading part
        _addEditFor(
          unformattedStart,
          unformattedStart + unformattedOffset,
          formattedStart,
          formattedStart + formattedOffset,
        );
        // Call us again for the trailing part
        _addEditFor(
          unformattedStart + unformattedOffset,
          unformattedEnd,
          formattedStart + formattedOffset,
          formattedEnd,
        );
        return;
      }

      // If we're formatting only a range, skip over any segments that don't
      // fall entirely within that range.
      if (unformattedStart < _rangeStart || unformattedEnd > _rangeEnd) {
        return;
      }
    }

    if (unformattedWhitespace == formattedWhitespace) {
      return;
    }

    var startOffset = unformattedStart;
    var endOffset = unformattedEnd;
    var oldText = unformattedWhitespace;
    var newText = formattedWhitespace;

    // Simplify some common cases where the new whitespace is a subset of
    // the old.
    // Remove common prefixes.
    int commonPrefixLength = 0;
    while (commonPrefixLength < oldText.length &&
        commonPrefixLength < newText.length &&
        oldText[commonPrefixLength] == newText[commonPrefixLength]) {
      commonPrefixLength++;
    }
    if (commonPrefixLength != 0) {
      oldText = oldText.substring(commonPrefixLength);
      newText = newText.substring(commonPrefixLength);
      startOffset += commonPrefixLength;
    }

    // Remove common suffixes.
    int commonSuffixLength = 0;
    while (commonSuffixLength < oldText.length &&
        commonSuffixLength < newText.length &&
        oldText[oldText.length - 1 - commonSuffixLength] ==
            newText[newText.length - 1 - commonSuffixLength]) {
      commonSuffixLength++;
    }
    if (commonSuffixLength != 0) {
      oldText = oldText.substring(0, oldText.length - commonSuffixLength);
      newText = newText.substring(0, newText.length - commonSuffixLength);
      endOffset -= commonSuffixLength;
    }

    // Unless allowing any differences, validate that the replaced and
    // replacement text only contain characters that we expected the formatter
    // to have changed. If the change contains other characters, it's likely
    // the token offsets used were incorrect and it's better to not modify the
    // code than potentially corrupt it.
    if (!allowAnyContentDifferences &&
        (!_isValidFormatterChange(oldText) ||
            !_isValidFormatterChange(newText))) {
      return;
    }

    // Finally, append the edit for this whitespace.
    // Note: As with all LSP edits, offsets are based on the original location
    // as they are applied in one shot. They should not account for the previous
    // edits in the same set.
    _edits.add(
      TextEdit(
        range: Range(
          start: toPosition(_lineInfo.getLocation(startOffset)),
          end: toPosition(_lineInfo.getLocation(endOffset)),
        ),
        newText: newText,
      ),
    );
  }

  /// Generates fallback results for if we are unable to minimize edits
  /// because the token streams differ in a way that we don't expect. This may
  /// indicate a bug in the formatter, or a bug in our assumptions about what
  /// tokens may change between formatted/unformatted (such as brackets - see
  /// https://github.com/Dart-Code/Dart-Code/issues/5169).
  List<TextEdit> _generateFallback() {
    if (_rangeStart == null && _rangeEnd == null) {
      // If this was a full document format, we can fall back to a single edit
      // for the whole document.
      return generateFullEdit(_lineInfo, _unformatted, _formatted);
    } else {
      // If we were a range format, we are unable to reduce the edits to that
      // range so we should format nothing.
      return [];
    }
  }

  /// Whether [token] is allowed to exist only in the formatted or unformatted
  /// code.
  ///
  /// For example, the formatted may add or remove commas or semicolons and we
  /// should not consider these errors.
  bool _isAllowedOptional(Token token) {
    return allowedAddOrRemovedTokens.contains(token.type);
  }

  /// Iterates over a token stream returning all tokens including comments.
  Iterable<Token> _iterateAllTokens(Token token) sync* {
    while (!token.isEof) {
      Token? commentToken = token.precedingComments;
      while (commentToken != null) {
        yield commentToken;
        commentToken = commentToken.next;
      }
      yield token;
      token = token.next!;
    }
  }

  /// A helper to check whether the token [left] has been substituted in [right]
  /// and returns the total number of tokens it was subtituted with.
  ///
  /// For example, if [left] is a `GT_GT_GT` token and [right] is a sequence
  /// starting `GT`, `GT, `GT`, returns 3.
  ///
  /// Returns `null` if [right] does not begin with an allowed substitution.
  int? _substitutes(Token left, Token right) {
    var possibleSubstitutions = allowedSubstitutions[left.type];
    if (possibleSubstitutions == null) return null;

    // For each possible sequence of substitutes...
    for (var possibleSubstitution in possibleSubstitutions) {
      var numSubtitutes = possibleSubstitution.length;
      var match = true;
      Token? current = right;

      // Check if the first `possibleSubstitution.length` tokens match the
      // allowed substitution.
      for (int i = 0; i < numSubtitutes && match; i++) {
        if (possibleSubstitution[i] != current?.type) {
          match = false;
          break;
        }
        current = current?.next;
      }

      if (match) {
        return numSubtitutes;
      }
    }

    return null;
  }

  /// Parse and return the first of the given Dart source, `null` if code cannot
  /// be parsed.
  static Token? _parse(String s, FeatureSet featureSet) {
    try {
      var scanner = Scanner(
        _SourceMock.instance,
        CharSequenceReader(s),
        AnalysisErrorListener.NULL_LISTENER,
      )..configureFeatures(
        featureSetForOverriding: featureSet,
        featureSet: featureSet,
      );
      return scanner.tokenize();
    } catch (e) {
      return null;
    }
  }
}

class _SourceMock implements Source {
  static final Source instance = _SourceMock();

  @override
  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
