// 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
   * [signature]. 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(
    FunctionType signature, {
    StringBuffer displayTextBuffer,
    bool invokeSuper: true,
  });

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

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

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