// Copyright (c) 2017, 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/dart/analysis/session.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';

/// A builder used to build a [SourceChange].
///
/// Clients may not extend, implement or mix-in this class.
abstract class ChangeBuilder {
  /// Initialize a newly created change builder. If the builder will be used to
  /// create changes for Dart files, then either a [session] or a [workspace]
  /// must be provided (but not both).
  factory ChangeBuilder(
      {AnalysisSession session,
      ChangeWorkspace workspace,
      String eol}) = ChangeBuilderImpl;

  /// Return the range of the selection for the change being built, or `null` if
  /// there is no selection.
  SourceRange get selectionRange;

  /// Return the source change that was built. The source change will not be
  /// complete until all of the futures returned by the add*FileEdit methods
  /// have completed.
  SourceChange get sourceChange;

  /// Use the [buildFileEdit] function to create a collection of edits to the
  /// file with the given [path]. The edits will be added to the source change
  /// that is being built.
  ///
  /// The builder passed to the [buildFileEdit] function has additional support
  /// for working with Dart source files.
  Future<void> addDartFileEdit(
      String path, void Function(DartFileEditBuilder builder) buildFileEdit,
      {ImportPrefixGenerator importPrefixGenerator});

  /// Use the [buildFileEdit] function to create a collection of edits to the
  /// file with the given [path]. The edits will be added to the source change
  /// that is being built.
  @Deprecated('Use either addDartFileEdit or addGenericFileEdit')
  Future<void> addFileEdit(
      String path, void Function(FileEditBuilder builder) buildFileEdit);

  /// Use the [buildFileEdit] function to create a collection of edits to the
  /// file with the given [path]. The edits will be added to the source change
  /// that is being built.
  ///
  /// The builder passed to the [buildFileEdit] function has no special support
  /// for any particular kind of file.
  Future<void> addGenericFileEdit(
      String path, void Function(FileEditBuilder builder) buildFileEdit);

  /// Return a copy of this change builder that is constructed in such as was
  /// that changes to the copy will not effect this change builder.
  ChangeBuilder copy();

  /// Set the selection for the change being built to the given [position].
  void setSelection(Position position);
}

/// A builder used to build a [SourceEdit] as part of a [SourceFileEdit].
///
/// Clients may not extend, implement or mix-in this class.
abstract class EditBuilder {
  /// Add a region of text that is part of the linked edit group with the given
  /// [groupName]. The [buildLinkedEdit] function is used to write the content
  /// of the region of text and to add suggestions for other possible values for
  /// that region.
  void addLinkedEdit(String groupName,
      void Function(LinkedEditBuilder builder) buildLinkedEdit);

  /// Add the given text as a linked edit group with the given [groupName]. If
  /// both a [kind] and a list of [suggestions] are provided, they will be added
  /// as suggestions to the group with the given kind.
  ///
  /// Throws an [ArgumentError] if either [kind] or [suggestions] are provided
  /// without the other.
  void addSimpleLinkedEdit(String groupName, String text,
      {LinkedEditSuggestionKind kind, List<String> suggestions});

  /// Set the selection to cover all of the code written by the given [writer].
  void selectAll(void Function() writer);

  /// Set the selection to the current location within the edit being built.
  void selectHere();

  /// Add the given [string] to the content of the current edit.
  void write(String string);

  /// Add the given [string] to the content of the current edit and then add an
  /// end-of-line marker.
  void writeln([String string]);
}

/// A builder used to build a [SourceFileEdit] within a [SourceChange].
///
/// Clients may not extend, implement or mix-in this class.
abstract class FileEditBuilder {
  /// Add a deletion of text specified by the given [range]. The [range] is
  /// relative to the original source. This is fully equivalent to
  ///
  ///     addSimpleReplacement(range, '');
  void addDeletion(SourceRange range);

  /// Add an insertion of text at the given [offset]. The [offset] is relative
  /// to the original source. The [buildEdit] function is used to write the text
  /// to be inserted. This is fully equivalent to
  ///
  ///     addReplacement(new SourceRange(offset, 0), buildEdit);
  void addInsertion(int offset, void Function(EditBuilder builder) buildEdit);

  /// Add the region of text specified by the given [range] to the linked edit
  /// group with the given [groupName]. The [range] is relative to the original
  /// source. This is typically used to include pre-existing regions of text in
  /// a group. If the region to be included is part of newly generated text,
  /// then the method [EditBuilder.addLinkedEdit] should be used instead.
  void addLinkedPosition(SourceRange range, String groupName);

  /// Add a replacement of text specified by the given [range]. The [range] is
  /// relative to the original source. The [buildEdit] function is used to write
  /// the text that will replace the specified region.
  void addReplacement(
      SourceRange range, void Function(EditBuilder builder) buildEdit);

  /// Add an insertion of the given [text] at the given [offset]. The [offset]
  /// is relative to the original source. This is fully equivalent to
  ///
  ///     addInsertion(offset, (EditBuilder builder) {
  ///       builder.write(text);
  ///     });
  void addSimpleInsertion(int offset, String text);

  /// Add a replacement of the text specified by the given [range]. The [range]
  /// is relative to the original source. The original content will be replaced
  /// by the given [text]. This is fully equivalent to
  ///
  ///     addReplacement(offset, length, (EditBuilder builder) {
  ///       builder.write(text);
  ///     });
  void addSimpleReplacement(SourceRange range, String text);
}

/// A builder used to build a [LinkedEdit] region within an edit.
///
/// Clients may not extend, implement or mix-in this class.
abstract class LinkedEditBuilder {
  /// Add the given [value] as a suggestion with the given [kind].
  void addSuggestion(LinkedEditSuggestionKind kind, String value);

  /// Add each of the given [values] as a suggestion with the given [kind].
  void addSuggestions(LinkedEditSuggestionKind kind, Iterable<String> values);

  /// Add the given [string] to the content of the current edit.
  void write(String string);

  /// Add the given [string] to the content of the current edit and then add an
  /// end-of-line marker.
  void writeln([String string]);
}
