// Copyright (c) 2015, 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.

/// Defines [StringEditBuffer], a buffer that can be used to apply edits on a
/// string.
// TODO(sigmund): this should move to a separate package.
library dart2js.src.string_edit_buffer;

/// A buffer meant to apply edits on a string (rather than building a string
/// from scratch). Each change is described using the location information on
/// the original string. Internally this buffer keeps track of how a
/// modification in one portion can offset a modification further down the
/// string.
class StringEditBuffer {
  final String original;
  final _edits = <_StringEdit>[];

  StringEditBuffer(this.original);

  bool get hasEdits => _edits.isNotEmpty;

  /// Edit the original text, replacing text on the range [begin] and
  /// exclusive [end] with the [replacement] string.
  void replace(int begin, int end, String replacement, [int? sortId]) {
    _edits.add(_StringEdit(begin, end, replacement, sortId));
  }

  /// Insert [string] at [offset].
  /// Equivalent to `replace(offset, offset, string)`.
  void insert(int offset, String string, [sortId]) =>
      replace(offset, offset, string, sortId);

  /// Remove text from the range [begin] to exclusive [end].
  /// Equivalent to `replace(begin, end, '')`.
  void remove(int begin, int end) => replace(begin, end, '');

  /// Applies all pending [edit]s and returns a new string.
  ///
  /// This method is non-destructive: it does not discard existing edits or
  /// change the [original] string. Further edits can be added and this method
  /// can be called again.
  ///
  /// Throws [UnsupportedError] if the edits were overlapping. If no edits were
  /// made, the original string will be returned.
  @override
  String toString() {
    var sb = StringBuffer();
    if (_edits.isEmpty) return original;

    // Sort edits by start location.
    _edits.sort();

    int consumed = 0;
    for (var edit in _edits) {
      if (consumed > edit.begin) {
        sb = StringBuffer();
        sb.write('overlapping edits. Insert at offset ');
        sb.write(edit.begin);
        sb.write(' but have consumed ');
        sb.write(consumed);
        sb.write(' input characters. List of edits:');
        for (var e in _edits) {
          sb.write('\n    ');
          sb.write(e);
        }
        throw UnsupportedError(sb.toString());
      }

      // Add characters from the original string between this edit and the last
      // one, if any.
      var betweenEdits = original.substring(consumed, edit.begin);
      sb.write(betweenEdits);
      sb.write(edit.string);
      consumed = edit.end;
    }

    // Add any text from the end of the original string that was not replaced.
    sb.write(original.substring(consumed));
    return sb.toString();
  }
}

/// A single edit in a [StringEditBuffer].
class _StringEdit implements Comparable<_StringEdit> {
  // Offset where edit begins
  final int begin;

  // Offset where edit ends
  final int end;

  // Sort index as a tie-breaker for edits that have the same location.
  final int sortId;

  // String to insert
  final String string;

  _StringEdit(this.begin, this.end, this.string, [int? sortId])
      : sortId = sortId ?? begin;

  int get length => end - begin;

  @override
  String toString() => '(Edit @ $begin,$end: "$string")';

  @override
  int compareTo(_StringEdit other) {
    int diff = begin - other.begin;
    if (diff != 0) return diff;
    diff = end - other.end;
    if (diff != 0) return diff;
    // use edit order as a tie breaker
    return sortId - other.sortId;
  }
}
