// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import 'package:meta/meta.dart';

/// A class representing a change on a [String], intended to be compatible with
/// `package:analysis_server`'s [SourceEdit].
///
/// For example, changing a string from
/// ```
/// foo: foobar
/// ```
/// to
/// ```
/// foo: barbar
/// ```
/// will be represented by `SourceEdit(offset: 4, length: 3, replacement: 'bar')`
@sealed
class SourceEdit {
  /// The offset from the start of the string where the modification begins.
  final int offset;

  /// The length of the substring to be replaced.
  final int length;

  /// The replacement string to be used.
  final String replacement;

  /// Creates a new [SourceEdit] instance. [offset], [length] and [replacement]
  /// must be non-null, and [offset] and [length] must be non-negative.
  factory SourceEdit(int offset, int length, String replacement) =>
      SourceEdit._(offset, length, replacement);

  SourceEdit._(this.offset, this.length, this.replacement) {
    ArgumentError.checkNotNull(offset, 'offset');
    ArgumentError.checkNotNull(length, 'length');
    ArgumentError.checkNotNull(replacement, 'replacement');
    RangeError.checkNotNegative(offset);
    RangeError.checkNotNegative(length);
  }

  @override
  bool operator ==(Object other) {
    if (other is SourceEdit) {
      return offset == other.offset &&
          length == other.length &&
          replacement == other.replacement;
    }

    return false;
  }

  @override
  int get hashCode => offset.hashCode ^ length.hashCode ^ replacement.hashCode;

  /// Constructs a SourceEdit from JSON.
  ///
  /// **Example:**
  /// ```dart
  /// final edit = {
  ///   'offset': 1,
  ///   'length': 2,
  ///   'replacement': 'replacement string'
  /// };
  ///
  /// final sourceEdit = SourceEdit.fromJson(edit);
  /// ```
  factory SourceEdit.fromJson(Map<String, dynamic> json) {
    ArgumentError.checkNotNull(json, 'json');

    if (json is Map) {
      final offset = json['offset'];
      final length = json['length'];
      final replacement = json['replacement'];

      if (offset is int && length is int && replacement is String) {
        return SourceEdit(offset, length, replacement);
      }
    }
    throw FormatException('Invalid JSON passed to SourceEdit');
  }

  /// Encodes this object as JSON-compatible structure.
  ///
  /// **Example:**
  /// ```dart
  /// import 'dart:convert' show jsonEncode;
  ///
  /// final edit = SourceEdit(offset, length, 'replacement string');
  /// final jsonString = jsonEncode(edit.toJson());
  /// print(jsonString);
  /// ```
  Map<String, dynamic> toJson() {
    return {'offset': offset, 'length': length, 'replacement': replacement};
  }

  @override
  String toString() => 'SourceEdit($offset, $length, "$replacement")';

  /// Applies a series of [SourceEdit]s to an original string, and return the
  /// final output.
  ///
  /// [edits] should be in order i.e. the first [SourceEdit] in [edits] should
  /// be the first edit applied to [original].
  ///
  /// **Example:**
  /// ```dart
  /// const original = 'YAML: YAML';
  /// final sourceEdits = [
  ///        SourceEdit(6, 4, "YAML Ain't Markup Language"),
  ///        SourceEdit(6, 4, "YAML Ain't Markup Language"),
  ///        SourceEdit(0, 4, "YAML Ain't Markup Language")
  ///      ];
  /// final result = SourceEdit.applyAll(original, sourceEdits);
  /// ```
  /// **Expected result:**
  /// ```dart
  /// "YAML Ain't Markup Language: YAML Ain't Markup Language Ain't Markup
  /// Language"
  /// ```
  static String applyAll(String original, Iterable<SourceEdit> edits) {
    ArgumentError.checkNotNull(original, 'original');
    ArgumentError.checkNotNull(edits, 'edits');

    return edits.fold(original, (current, edit) => edit.apply(current));
  }

  /// Applies one [SourceEdit]s to an original string, and return the final
  /// output.
  ///
  /// **Example:**
  /// ```dart
  /// final edit = SourceEdit(4, 3, 'bar');
  /// final originalString = 'foo: foobar';
  /// print(edit.apply(originalString)); // 'foo: barbar'
  /// ```
  String apply(String original) {
    ArgumentError.checkNotNull(original, 'original');

    return original.replaceRange(offset, offset + length, replacement);
  }
}
