// 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/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';

/// The optional generator for prefix that should be used for new imports.
typedef ImportPrefixGenerator = String Function(Uri);

/// An [EditBuilder] used to build edits in Dart files.
///
/// Clients may not extend, implement or mix-in this class.
abstract class DartEditBuilder implements EditBuilder {
  @override
  void addLinkedEdit(String groupName,
      void Function(DartLinkedEditBuilder builder) buildLinkedEdit);

  /// Write the code for a declaration of a class with the given [name]. If a
  /// list of [interfaces] is provided, then the class will implement those
  /// interfaces. If [isAbstract] is `true`, then the class will be abstract. If
  /// a [membersWriter] is provided, then it will be invoked to allow members to
  /// be generated. If a list of [mixins] is provided, then the class
  /// will mix in those classes. If a [nameGroupName] is provided, then the name
  /// of the class will be included in the linked edit group with that name. If
  /// a [superclass] is given then it will be the superclass of the class. (If a
  /// list of [mixins] is provided but no [superclass] is given then the class
  /// will extend `Object`.)
  void writeClassDeclaration(String name,
      {Iterable<DartType>? interfaces,
      bool isAbstract = false,
      void Function()? membersWriter,
      Iterable<DartType>? mixins,
      String? nameGroupName,
      DartType? superclass,
      String? superclassGroupName});

  /// Write the code for a constructor declaration in the class with the given
  /// [className]. If [isConst] is `true`, then the constructor will be marked
  /// as being a `const` constructor. If a [constructorName] is provided, then
  /// the constructor will have the given name. If both a constructor name and
  /// a [constructorNameGroupName] is provided, then the name of the constructor
  /// will be included in the linked edit group with that name. If a
  /// [parameterWriter] is provided then it is used to write the constructor
  /// parameters (enclosing parenthesis are written for you). Otherwise, if an
  /// [argumentList] is provided then the constructor will have parameters that
  /// match the given arguments. If no argument list is given, but a list of
  /// [fieldNames] is provided, then field formal parameters will be created for
  /// each of the field names. If an [initializerWriter] is provided then it is
  /// used to write the constructor initializers (the ` : ` prefix is written
  /// for you). If a [bodyWriter] is provided then it is used to write the
  /// constructor body, otherwise an empty body is written.
  void writeConstructorDeclaration(String className,
      {ArgumentList? argumentList,
      void Function()? bodyWriter,
      String? classNameGroupName,
      SimpleIdentifier? constructorName,
      String? constructorNameGroupName,
      List<String>? fieldNames,
      void Function()? initializerWriter,
      bool isConst = false,
      void Function()? parameterWriter});

  /// Write the code for a declaration of a field with the given [name]. If an
  /// [initializerWriter] is provided, it will be invoked to write the content
  /// of the initializer. (The equal sign separating the field name from the
  /// initializer expression will automatically be written.) If [isConst] is
  /// `true`, then the declaration will be preceded by the `const` keyword. If
  /// [isFinal] is `true`, then the declaration will be preceded by the `final`
  /// keyword. (If both [isConst] and [isFinal] are `true`, then only the
  /// `const` keyword will be written.) If [isStatic] is `true`, then the
  /// declaration will be preceded by the `static` keyword. If a [nameGroupName]
  /// is provided, the name of the field will be included in the linked edit
  /// group with that name. If a [type] is provided, then it will be used as the
  /// type of the field. (The keyword `var` will be provided automatically when
  /// required.) If a [typeGroupName] is provided, then if a type was written
  /// it will be in the linked edit group with that name.
  void writeFieldDeclaration(String name,
      {void Function()? initializerWriter,
      bool isConst = false,
      bool isFinal = false,
      bool isStatic = false,
      String? nameGroupName,
      DartType? type,
      String? typeGroupName});

  /// Write the code for a declaration of a function with the given [name]. If a
  /// [bodyWriter] is provided, it will be invoked to write the body of the
  /// function. (The space between the name and the body will automatically be
  /// written.) If [isStatic] is `true`, then the declaration will be preceded
  /// by the `static` keyword. If a [nameGroupName] is provided, the name of the
  /// function will be included in the linked edit group with that name. If a
  /// [returnType] is provided, then it will be used as the return type of the
  /// function. If a [returnTypeGroupName] is provided, then if a return type
  /// was written it will be in the linked edit group with that name. If a
  /// [parameterWriter] is provided, then it will be invoked to write the
  /// declarations of the parameters to the function. (The parentheses around
  /// the parameters will automatically be written.)
  void writeFunctionDeclaration(String name,
      {void Function()? bodyWriter,
      bool isStatic = false,
      String? nameGroupName,
      void Function()? parameterWriter,
      DartType? returnType,
      String? returnTypeGroupName});

  /// Write the code for a declaration of a getter with the given [name]. If a
  /// [bodyWriter] is provided, it will be invoked to write the body of the
  /// getter. (The space between the name and the body will automatically be
  /// written.) If [isStatic] is `true`, then the declaration will be preceded
  /// by the `static` keyword. If a [nameGroupName] is provided, the name of the
  /// getter will be included in the linked edit group with that name. If a
  /// [returnType] is provided, then it will be used as the return type of the
  /// getter. If a [returnTypeGroupName] is provided, then if a return type was
  /// written it will be in the linked edit group with that name.
  void writeGetterDeclaration(String name,
      {void Function() bodyWriter,
      bool isStatic = false,
      String nameGroupName,
      DartType returnType,
      String returnTypeGroupName});

  /// Write the given [name], possibly with a prefix, assuming that the name can
  /// be imported from any of the given [uris].
  void writeImportedName(List<Uri> uris, String name);

  /// Write the code for a declaration of a local variable with the given
  /// [name]. If an [initializerWriter] is provided, it will be invoked to write
  /// the content of the initializer. (The equal sign separating the variable
  /// name from the initializer expression will automatically be written.) If
  /// [isConst] is `true`, then the declaration will be preceded by the `const`
  /// keyword. If [isFinal] is `true`, then the declaration will be preceded by
  /// the `final` keyword. (If both [isConst] and [isFinal] are `true`, then
  /// only the `const` keyword will be written.) If a [nameGroupName] is
  /// provided, the name of the variable will be included in the linked edit
  /// group with that name. If a [type] is provided, then it will be used as the
  /// type of the variable. (The keyword `var` will be provided automatically
  /// when required.) If a [typeGroupName] is provided, then if a type was
  /// written it will be in the linked edit group with that name.
  void writeLocalVariableDeclaration(String name,
      {void Function()? initializerWriter,
      bool isConst = false,
      bool isFinal = false,
      String? nameGroupName,
      DartType? type,
      String? typeGroupName});

  /// Write the code for a declaration of a mixin with the given [name]. If a
  /// list of [interfaces] is provided, then the mixin will implement those
  /// interfaces. If a [membersWriter] is provided, then it will be invoked to
  /// allow members to be generated. If a [nameGroupName] is provided, then the
  /// name of the class will be included in the linked edit group with that
  /// name.
  void writeMixinDeclaration(String name,
      {Iterable<DartType>? interfaces,
      void Function()? membersWriter,
      String? nameGroupName,
      Iterable<DartType>? superclassConstraints});

  /// Append a placeholder for an override of the specified inherited [element].
  /// If provided, write a string value suitable for display (e.g., in a
  /// completion popup) in the given [displayTextBuffer]. If [invokeSuper] is
  /// `true`, then the corresponding `super.name()` will be added in the body.
  void writeOverride(
    ExecutableElement element, {
    StringBuffer? displayTextBuffer,
    bool invokeSuper = false,
  });

  /// Write the code for a single parameter with the given [name].
  ///
  /// If a [methodBeingCopied] is provided, then type parameters defined by that
  /// method are assumed to be part of what is being written and hence valid
  /// types.
  ///
  /// If a [type] is provided, then it will be used as the type of the
  /// parameter.
  ///
  /// If a [nameGroupName] is provided, then the name of the parameter will be
  /// included in a linked edit.
  ///
  /// If a [type] and [typeGroupName] are both provided, then the type of the
  /// parameter will be included in a linked edit.
  ///
  /// If [isCovariant] is `true` then the keyword `covariant` will be included
  /// in the parameter declaration.
  ///
  /// If [isRequiredNamed] is `true` then either the keyword `required` or the
  /// annotation `@required` will be included in the parameter declaration.
  void writeParameter(String name,
      {bool isCovariant,
      bool isRequiredNamed,
      ExecutableElement? methodBeingCopied,
      String? nameGroupName,
      DartType? type,
      String? typeGroupName});

  /// Write the code for a parameter that would match the given [argument]. The
  /// name of the parameter will be generated based on the type of the argument,
  /// but if the argument type is not known the [index] will be used to compose
  /// a name. In any case, the set of [usedNames] will be used to ensure that
  /// the name is unique (and the chosen name will be added to the set).
  void writeParameterMatchingArgument(
      Expression argument, int index, Set<String> usedNames);

  /// Write the code for a list of [parameters], including the surrounding
  /// parentheses.
  ///
  /// If a [methodBeingCopied] is provided, then type parameters defined by that
  /// method are assumed to be part of what is being written and hence valid
  /// types.
  void writeParameters(Iterable<ParameterElement> parameters,
      {ExecutableElement? methodBeingCopied});

  /// Write the code for a list of parameters that would match the given list of
  /// [arguments]. The surrounding parentheses are *not* written.
  void writeParametersMatchingArguments(ArgumentList arguments);

  /// Write the code that references the [element]. If the [element] is a
  /// top-level element that has not been imported into the current library,
  /// imports will be updated.
  void writeReference(Element element);

  /// Write the code for a declaration of a setter with the given [name]. If a
  /// [bodyWriter] is provided, it will be invoked to write the body of the
  /// setter. (The space between the name and the body will automatically be
  /// written.) If [isStatic] is `true`, then the declaration will be preceded
  /// by the `static` keyword. If a [nameGroupName] is provided, the name of the
  /// getter will be included in the linked edit group with that name. If a
  /// [parameterType] is provided, then it will be used as the type of the
  /// parameter. If a [parameterTypeGroupName] is provided, then if a parameter
  /// type was written it will be in the linked edit group with that name.
  void writeSetterDeclaration(String name,
      {void Function()? bodyWriter,
      bool isStatic = false,
      String? nameGroupName,
      DartType? parameterType,
      String? parameterTypeGroupName});

  /// Write the code for a type annotation for the given [type]. If the [type]
  /// is either `null` or represents the type 'dynamic', then the behavior
  /// depends on whether a type is [required]. If [required] is `true`, then
  /// 'var' will be written; otherwise, nothing is written.
  ///
  /// If the [groupName] is not `null`, then the name of the type (including
  /// type parameters) will be included as a region in the linked edit group
  /// with that name. If the [groupName] is not `null` and
  /// [addSupertypeProposals] is `true`, then all of the supertypes of the
  /// [type] will be added as suggestions for alternatives to the type name.
  ///
  /// If a [methodBeingCopied] is provided, then type parameters defined by that
  /// method are assumed to be part of what is being written and hence valid
  /// types.
  ///
  /// Return `true` if some text was written.
  bool writeType(DartType? type,
      {bool addSupertypeProposals = false,
      String? groupName,
      ExecutableElement? methodBeingCopied,
      bool required = false});

  /// Write the code to declare the given [typeParameter]. The enclosing angle
  /// brackets are not automatically written.
  ///
  /// If a [methodBeingCopied] is provided, then type parameters defined by that
  /// method are assumed to be part of what is being written and hence valid
  /// types.
  void writeTypeParameter(TypeParameterElement typeParameter,
      {ExecutableElement? methodBeingCopied});

  /// Write the code to declare the given list of [typeParameters]. The
  /// enclosing angle brackets are automatically written.
  ///
  /// If a [methodBeingCopied] is provided, then type parameters defined by that
  /// method are assumed to be part of what is being written and hence valid
  /// types.
  void writeTypeParameters(List<TypeParameterElement> typeParameters,
      {ExecutableElement? methodBeingCopied});

  /// Write the code for a comma-separated list of [types], optionally prefixed
  /// by a [prefix]. If the list of [types] is `null` or does not contain any
  /// types, then nothing will be written.
  void writeTypes(Iterable<DartType>? types, {String? prefix});
}

/// A [FileEditBuilder] used to build edits for Dart files.
///
/// Clients may not extend, implement or mix-in this class.
abstract class DartFileEditBuilder implements FileEditBuilder {
  @override
  void addInsertion(
      int offset, void Function(DartEditBuilder builder) buildEdit);

  @override
  void addReplacement(
      SourceRange range, void Function(DartEditBuilder builder) buildEdit);

  /// Create one or more edits that will convert the given function [body] from
  /// being synchronous to be asynchronous. This includes adding the `async`
  /// modifier to the body as well as potentially replacing the return type of
  /// the function to `Future`.
  ///
  /// There is currently a limitation in that the function body must not be a
  /// generator.
  ///
  /// Throws an [ArgumentError] if the function body is not both synchronous and
  /// a non-generator.
  void convertFunctionFromSyncToAsync(
      FunctionBody body, TypeProvider typeProvider);

  /// Format the code covered by the [range].
  ///
  /// If there are any edits that are in the [range], these edits are applied
  /// first, and replaced with a single new edit that produces the resulting
  /// formatted code. The [range] is relative to the original code.
  void format(SourceRange range);

  /// Arrange to have an import added for the library with the given [uri].
  ///
  /// Returns the text of the URI that will be used in the import directive.
  /// It can be different than the given [Uri].
  String importLibrary(Uri uri);

  /// Ensure that the library with the given [uri] is imported.
  ///
  /// If there is already an import for the requested library, return the import
  /// prefix of the existing import directive.
  ///
  /// If there is no existing import, a new import is added.
  ImportLibraryElementResult importLibraryElement(Uri uri);

  /// Optionally create an edit to replace the given [typeAnnotation] with the
  /// type `Future` (with the given type annotation as the type argument). The
  /// [typeProvider] is used to check the current type, because if it is already
  /// `Future` no edit will be added.
  void replaceTypeWithFuture(
      TypeAnnotation typeAnnotation, TypeProvider typeProvider);
}

/// A [LinkedEditBuilder] used to build linked edits for Dart files.
///
/// Clients may not extend, implement or mix-in this class.
abstract class DartLinkedEditBuilder implements LinkedEditBuilder {
  /// Add the given [type] and all of its supertypes (other than mixins) as
  /// suggestions for the current linked edit group.
  void addSuperTypesAsSuggestions(DartType? type);
}

/// Information about a library to import.
abstract class ImportLibraryElementResult {
  /// If the library is already imported with a prefix, or should be imported
  /// with a prefix, the prefix name (without `.`). Otherwise `null`.
  String? get prefix;
}
