// Copyright (c) 2022, 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:math' as math;

import 'package:analysis_server/src/protocol_server.dart' as server
    hide AnalysisError;
import 'package:collection/collection.dart';

/// Builds an LSP snippet string using the supplied edit groups.
///
/// [editGroups] are provided as absolute positions, where the edit will be
/// made starting at [editOffset].
///
/// [selectionOffset] is also absolute and assumes [text] will be
/// inserted at [editOffset].
String buildSnippetStringForEditGroups(
  String text, {
  required String filePath,
  required List<server.LinkedEditGroup> editGroups,
  required int editOffset,
  int? selectionOffset,
}) =>
    _buildSnippetString(
      text,
      filePath: filePath,
      editGroups: editGroups,
      editGroupsOffset: editOffset,
      selectionOffset:
          selectionOffset != null ? selectionOffset - editOffset : null,
    );

/// Builds an LSP snippet string with supplied ranges as tab stops.
///
/// [tabStopOffsetLengthPairs] are relative to the supplied text.
String buildSnippetStringWithTabStops(
  String text,
  List<int>? tabStopOffsetLengthPairs,
) =>
    _buildSnippetString(
      text,
      filePath: null,
      tabStopOffsetLengthPairs: tabStopOffsetLengthPairs,
    );

/// Builds an LSP snippet string with supplied ranges as tab stops.
///
/// [tabStopOffsetLengthPairs] are relative to the supplied text.
///
/// [selectionOffset]/[selectionLength] form a tab stop that is always "number 0"
/// which is the final tab stop.
///
/// [editGroups] are provided as absolute positions, where [text] is known to
/// start at [editGroupsOffset] in the final document.
String _buildSnippetString(
  String text, {
  required String? filePath,
  List<int>? tabStopOffsetLengthPairs,
  int? selectionOffset,
  int? selectionLength,
  List<server.LinkedEditGroup>? editGroups,
  int editGroupsOffset = 0,
}) {
  tabStopOffsetLengthPairs ??= const [];
  editGroups ??= const [];
  assert(tabStopOffsetLengthPairs.length % 2 == 0);

  /// Helper to create a [SnippetPlaceholder] for each position in a linked
  /// edit group.
  Iterable<SnippetPlaceholder> convertEditGroup(
    int index,
    server.LinkedEditGroup editGroup,
  ) {
    final validPositions = editGroup.positions.where((p) => p.file == filePath);
    // Create a placeholder for each position in the group.
    return validPositions.map(
      (position) => SnippetPlaceholder(
        // Make the position relative to the supplied text.
        position.offset - editGroupsOffset,
        editGroup.length,
        suggestions: editGroup.suggestions
            .map((suggestion) => suggestion.value)
            .toList(),
        // Use the index as an ID to keep all related positions together (so
        // the remain "linked").
        linkedGroupId: index,
        // If there is no selection, no tabstops, and only a single edit group
        // allow it to be the final tabstop.
        isFinal: selectionOffset == null &&
            (tabStopOffsetLengthPairs?.isEmpty ?? false) &&
            editGroups?.length == 1,
      ),
    );
  }

  // Convert selection/tab stops/edit groups all into the same format
  // (`_SnippetPlaceholder`) so they can be handled in a single pass through
  // the text.
  final placeholders = [
    // Selection.
    if (selectionOffset != null)
      SnippetPlaceholder(selectionOffset, selectionLength ?? 0, isFinal: true),

    // Tab stops.
    for (var i = 0; i < tabStopOffsetLengthPairs.length - 1; i += 2)
      SnippetPlaceholder(
        tabStopOffsetLengthPairs[i],
        tabStopOffsetLengthPairs[i + 1],
        // If there's only a single tab stop (and no selection/editGroups), mark
        // it as the final stop so it exit "snippet mode" when tabbed to.
        isFinal: selectionOffset == null &&
            editGroups.isEmpty &&
            tabStopOffsetLengthPairs.length == 2,
      ),

    // Linked edit groups.
    ...editGroups.expandIndexed(convertEditGroup),
  ];

  // Remove any groups outside of the range (it's possible the edit groups apply
  // to a different edit in the collection).
  placeholders.removeWhere((placeholder) =>
      placeholder.offset < 0 ||
      placeholder.offset + placeholder.length > text.length);

  final builder = SnippetBuilder()..appendPlaceholders(text, placeholders);
  return builder.value;
}

/// A helper for building for snippets using LSP/TextMate syntax.
///
/// https://microsoft.github.io/language-server-protocol/specifications/specification-current/#snippet_syntax
///
///  - $1, $2, etc. are used for tab stops
///  - ${1:foo} inserts a placeholder of foo
///  - ${1|foo,bar|} inserts a placeholder of foo with a selection list
///      containing "foo" and "bar"
class SnippetBuilder {
  /// The constant `$0` used do indicate a final tab stop in the snippet syntax.
  static const finalTabStop = r'$0';

  final _buffer = StringBuffer();

  var _nextPlaceholder = 1;

  /// The built snippet text using the LSP snippet syntax.
  String get value => _buffer.toString();

  /// Appends a placeholder with a set of choices to choose from.
  ///
  /// If there are 0 or 1 choices, a placeholder will be inserted instead.
  ///
  /// Returns the placeholder number used.
  int appendChoice(Iterable<String> choices, {int? placeholderNumber}) {
    final uniqueChoices = choices.where((item) => item.isNotEmpty).toSet();

    // If there's only 0/1 items, we can downgrade this to a placeholder.
    if (uniqueChoices.length <= 1) {
      return appendPlaceholder(
        uniqueChoices.firstOrNull ?? '',
        placeholderNumber: placeholderNumber,
      );
    }

    placeholderNumber = _usePlaceholerNumber(placeholderNumber);

    final escapedChoices = uniqueChoices.map(escapeSnippetChoiceText).join(',');
    _buffer.write('\${$placeholderNumber|$escapedChoices|}');

    return placeholderNumber;
  }

  /// Appends a placeholder with the given text.
  ///
  /// If the text is empty, inserts a tab stop instead.
  ///
  /// Returns the placeholder number used.
  int appendPlaceholder(String text, {int? placeholderNumber}) {
    // If there's no text, we can downgrade this to a tab stop.
    if (text.isEmpty) {
      return appendTabStop(placeholderNumber: placeholderNumber);
    }

    placeholderNumber = _usePlaceholerNumber(placeholderNumber);

    final escapedText = escapeSnippetVariableText(text);
    _buffer.write('\${$placeholderNumber:$escapedText}');

    return placeholderNumber;
  }

  /// Appends a tab stop.
  ///
  /// Returns the placeholder number used.
  int appendTabStop({int? placeholderNumber}) {
    placeholderNumber = _usePlaceholerNumber(placeholderNumber);

    _buffer.write('\$$placeholderNumber');

    return placeholderNumber;
  }

  /// Appends normal text (escaping it as required).
  void appendText(String text) {
    _buffer.write(escapeSnippetPlainText(text));
  }

  /// Generates the current and next placeholder numbers.
  int _usePlaceholerNumber(int? placeholderNumber) {
    // If a number was not supplied, use thenext available one.
    placeholderNumber ??= _nextPlaceholder;
    // If the number we used was the highest seen, set the next one after it.
    _nextPlaceholder = math.max(_nextPlaceholder, placeholderNumber + 1);

    return placeholderNumber;
  }

  /// Escapes a string use inside a "choice" in a snippet.
  ///
  /// Similar to [escapeSnippetPlainText], but choices are delimited/separated
  /// by pipes and commas (`${1:|a,b,c|}`).
  static String escapeSnippetChoiceText(String input) => _escapeCharacters(
        input,
        RegExp(r'[$}\\\|,]'), // Replace any of $ } \ | ,
      );

  /// Escapes a string to be used in an LSP edit that uses Snippet mode where the
  /// text is outside of a snippet token.
  ///
  /// Snippets can contain special markup like `${a:b}` so `$` needs escaping
  /// as does `\` so it's not interpreted as an escape.
  static String escapeSnippetPlainText(String input) => _escapeCharacters(
        input,
        RegExp(r'[$\\]'), // Replace any of $ \
      );

  /// Escapes a string to be used inside a snippet token.
  ///
  /// Similar to [escapeSnippetPlainText] but additionally escapes `}` so that the
  /// token is not ended early if the included text contains braces.
  static String escapeSnippetVariableText(String input) => _escapeCharacters(
        input,
        RegExp(r'[$}\\]'), // Replace any of $ } \
      );

  /// Escapes [pattern] in [input] with backslashes.
  static String _escapeCharacters(String input, Pattern pattern) =>
      input.replaceAllMapped(pattern, (c) => '\\${c[0]}');
}

/// Information about an individual placeholder/tab stop in a piece of code.
///
/// Each placeholder represents a single position into the code, so a linked
/// edit group with 2 positions will be represented as two instances of this
/// class (with the same [linkedGroupId]).
class SnippetPlaceholder {
  final int offset;
  final int length;
  final List<String>? suggestions;
  final int? linkedGroupId;
  final bool isFinal;

  SnippetPlaceholder(
    this.offset,
    this.length, {
    this.suggestions,
    this.linkedGroupId,
    this.isFinal = false,
  });
}

/// Helpers for [SnippetBuilder] that do not relate to building the main snippet
/// syntax (for example, converting from intermediate structures).
extension SnippetBuilderExtensions on SnippetBuilder {
  void appendPlaceholders(String text, List<SnippetPlaceholder> placeholders) {
    // Ensure placeholders are in the order they're visible in the source so
    // tabbing through them doesn't appear to jump around.
    placeholders.sortBy<num>((placeholder) => placeholder.offset);

    // We need to use the same placeholder number for all placeholders in the
    // same linked group, so the first time we see a linked item, store its
    // placeholder number here, so subsequent placeholders for the same linked
    // group can reuse it.
    final placeholderIdForLinkedGroupId = <int, int>{};

    var offset = 0;
    for (final placeholder in placeholders) {
      // Add any text that came before this placeholder to the result.
      appendText(text.substring(offset, placeholder.offset));

      final linkedGroupId = placeholder.linkedGroupId;
      int? thisPaceholderNumber;
      // Override the placeholder number if it's the final one (0) or needs to
      // re-use an existing one for a linked group.
      if (placeholder.isFinal) {
        thisPaceholderNumber = 0;
      } else if (linkedGroupId != null) {
        thisPaceholderNumber = placeholderIdForLinkedGroupId[linkedGroupId];
      }

      // Append the placeholder/choices.
      final placeholderText = text.substring(
        placeholder.offset,
        placeholder.offset + placeholder.length,
      );
      // appendChoice handles mapping empty/single suggestions to a normal
      // placeholder.
      thisPaceholderNumber = appendChoice(
        [placeholderText, ...?placeholder.suggestions],
        placeholderNumber: thisPaceholderNumber,
      );

      // Track where we're up to.
      offset = placeholder.offset + placeholder.length;

      // Store the placeholder number used for linked groups so it can be reused
      // by subsequent references to it.
      if (linkedGroupId != null) {
        placeholderIdForLinkedGroupId[linkedGroupId] = thisPaceholderNumber;
      }
    }

    // Add any remaining text that was after the last placeholder.
    appendText(text.substring(offset));
  }
}
