// 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 'dart:async';

import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.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);

/**
 * A [ChangeBuilder] used to build changes in Dart files.
 *
 * Clients may not extend, implement or mix-in this class.
 */
abstract class DartChangeBuilder implements ChangeBuilder {
  /**
   * Initialize a newly created change builder.
   *
   * TODO(scheglov) Replace this constructor with using workspace.
   */
  factory DartChangeBuilder(AnalysisSession session) = DartChangeBuilderImpl;

  /**
   * 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.
   *
   * If [importPrefixGenerator] is provided, it will be asked to generate an
   * import prefix for every newly imported library.
   */
  @override
  Future<void> addFileEdit(
      String path, void buildFileEdit(DartFileEditBuilder builder),
      {ImportPrefixGenerator importPrefixGenerator});
}

/**
 * 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 buildLinkedEdit(DartLinkedEditBuilder builder));

  /**
   * 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 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 bodyWriter(),
      SimpleIdentifier constructorName,
      String constructorNameGroupName,
      List<String> fieldNames,
      void initializerWriter(),
      bool isConst: false,
      void 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 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 bodyWriter(),
      bool isStatic: false,
      String nameGroupName,
      void 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 bodyWriter(),
      bool isStatic: false,
      String nameGroupName,
      DartType returnType,
      String returnTypeGroupName});

  /**
   * 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 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 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.
   */
  void writeParameter(String name,
      {ExecutableElement methodBeingCopied, DartType type});

  /**
   * 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 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 buildEdit(DartEditBuilder builder));

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

  /**
   * 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;
}
