// Copyright (c) 2019, 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:math' as math;

import 'package:_fe_analyzer_shared/src/scanner/token.dart';
import 'package:analysis_server/plugin/edit/fix/fix_dart.dart';
import 'package:analysis_server/src/services/completion/dart/extension_cache.dart';
import 'package:analysis_server/src/services/correction/fix/dart/top_level_declarations.dart';
import 'package:analysis_server/src/services/correction/fix/data_driven/transform_override_set.dart';
import 'package:analysis_server/src/services/correction/util.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analyzer/dart/analysis/results.dart';
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/dart/element/type_provider.dart';
import 'package:analyzer/dart/element/type_system.dart';
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/source/source_range.dart';
import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
import 'package:analyzer_plugin/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';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';

/// An object that can compute a correction (fix or assist) in a Dart file.
abstract class CorrectionProducer extends SingleCorrectionProducer {
  /// Return the type for the class `bool` from `dart:core`.
  DartType get coreTypeBool => resolvedResult.typeProvider.boolType;

  /// Returns `true` if [node] is in a static context.
  bool get inStaticContext {
    // constructor initializer cannot reference "this"
    if (node.thisOrAncestorOfType<ConstructorInitializer>() != null) {
      return true;
    }
    // field initializer cannot reference "this"
    if (node.thisOrAncestorOfType<FieldDeclaration>() != null) {
      return true;
    }
    // static method
    var method = node.thisOrAncestorOfType<MethodDeclaration>();
    return method != null && method.isStatic;
  }

  Future<void> compute(ChangeBuilder builder);

  /// Return the class, enum or mixin declaration for the given [element].
  Future<ClassOrMixinDeclaration?> getClassOrMixinDeclaration(
      ClassElement element) async {
    var result = await sessionHelper.getElementDeclaration(element);
    var node = result?.node;
    if (node is ClassOrMixinDeclaration) {
      return node;
    }
    return null;
  }

  /// Return the extension declaration for the given [element].
  Future<ExtensionDeclaration?> getExtensionDeclaration(
      ExtensionElement element) async {
    var result = await sessionHelper.getElementDeclaration(element);
    var node = result?.node;
    if (node is ExtensionDeclaration) {
      return node;
    }
    return null;
  }

  /// Return the class element associated with the [target], or `null` if there
  /// is no such class element.
  ClassElement? getTargetClassElement(Expression target) {
    var type = target.staticType;
    if (type is InterfaceType) {
      return type.element;
    } else if (target is Identifier) {
      var element = target.staticElement;
      if (element is ClassElement) {
        return element;
      }
    }
    return null;
  }

  /// Returns an expected [DartType] of [expression], may be `null` if cannot be
  /// inferred.
  DartType? inferUndefinedExpressionType(Expression expression) {
    var parent = expression.parent;
    // myFunction();
    if (parent is ExpressionStatement) {
      if (expression is MethodInvocation) {
        return VoidTypeImpl.instance;
      }
    }
    // return myFunction();
    if (parent is ReturnStatement) {
      var executable = getEnclosingExecutableElement(expression);
      return executable?.returnType;
    }
    // int v = myFunction();
    if (parent is VariableDeclaration) {
      var variableDeclaration = parent;
      if (variableDeclaration.initializer == expression) {
        var variableElement = variableDeclaration.declaredElement;
        if (variableElement != null) {
          return variableElement.type;
        }
      }
    }
    // myField = 42;
    if (parent is AssignmentExpression) {
      var assignment = parent;
      if (assignment.leftHandSide == expression) {
        var rhs = assignment.rightHandSide;
        return rhs.staticType;
      }
    }
    // v = myFunction();
    if (parent is AssignmentExpression) {
      var assignment = parent;
      if (assignment.rightHandSide == expression) {
        if (assignment.operator.type == TokenType.EQ) {
          // v = myFunction();
          return assignment.writeType;
        } else {
          // v += myFunction();
          var method = assignment.staticElement;
          if (method != null) {
            var parameters = method.parameters;
            if (parameters.length == 1) {
              return parameters[0].type;
            }
          }
        }
      }
    }
    // v + myFunction();
    if (parent is BinaryExpression) {
      var binary = parent;
      var method = binary.staticElement;
      if (method != null) {
        if (binary.rightOperand == expression) {
          var parameters = method.parameters;
          return parameters.length == 1 ? parameters[0].type : null;
        }
      }
    }
    // foo( myFunction() );
    if (parent is ArgumentList) {
      var parameter = expression.staticParameterElement;
      return parameter?.type;
    }
    // bool
    {
      // assert( myFunction() );
      if (parent is AssertStatement) {
        var statement = parent;
        if (statement.condition == expression) {
          return coreTypeBool;
        }
      }
      // if ( myFunction() ) {}
      if (parent is IfStatement) {
        var statement = parent;
        if (statement.condition == expression) {
          return coreTypeBool;
        }
      }
      // while ( myFunction() ) {}
      if (parent is WhileStatement) {
        var statement = parent;
        if (statement.condition == expression) {
          return coreTypeBool;
        }
      }
      // do {} while ( myFunction() );
      if (parent is DoStatement) {
        var statement = parent;
        if (statement.condition == expression) {
          return coreTypeBool;
        }
      }
      // !myFunction()
      if (parent is PrefixExpression) {
        var prefixExpression = parent;
        if (prefixExpression.operator.type == TokenType.BANG) {
          return coreTypeBool;
        }
      }
      // binary expression '&&' or '||'
      if (parent is BinaryExpression) {
        var binaryExpression = parent;
        var operatorType = binaryExpression.operator.type;
        if (operatorType == TokenType.AMPERSAND_AMPERSAND ||
            operatorType == TokenType.BAR_BAR) {
          return coreTypeBool;
        }
      }
    }
    // we don't know
    return null;
  }
}

class CorrectionProducerContext {
  final int selectionOffset;
  final int selectionLength;
  final int selectionEnd;

  final CompilationUnit unit;
  final CorrectionUtils utils;
  final String file;

  final TypeProvider typeProvider;

  final AnalysisSession session;
  final AnalysisSessionHelper sessionHelper;
  final ResolvedUnitResult resolvedResult;
  final ChangeWorkspace workspace;

  /// TODO(migration) Make it non-nullable, specialize "fix" context?
  final DartFixContext? dartFixContext;

  /// A flag indicating whether the correction producers will be run in the
  /// context of applying bulk fixes.
  final bool applyingBulkFixes;

  final Diagnostic? diagnostic;

  final TransformOverrideSet? overrideSet;

  final AstNode node;

  CorrectionProducerContext._({
    required this.resolvedResult,
    required this.workspace,
    this.applyingBulkFixes = false,
    this.dartFixContext,
    this.diagnostic,
    required this.node,
    this.overrideSet,
    this.selectionOffset = -1,
    this.selectionLength = 0,
  })  : file = resolvedResult.path!,
        session = resolvedResult.session,
        sessionHelper = AnalysisSessionHelper(resolvedResult.session),
        typeProvider = resolvedResult.typeProvider,
        selectionEnd = selectionOffset + selectionLength,
        unit = resolvedResult.unit!,
        utils = CorrectionUtils(resolvedResult);

  /// Return `true` if the lint with the given [name] is enabled.
  bool isLintEnabled(String name) {
    var analysisOptions = session.analysisContext.analysisOptions;
    return analysisOptions.isLintEnabled(name);
  }

  static CorrectionProducerContext? create({
    required ResolvedUnitResult resolvedResult,
    required ChangeWorkspace workspace,
    bool applyingBulkFixes = false,
    DartFixContext? dartFixContext,
    Diagnostic? diagnostic,
    TransformOverrideSet? overrideSet,
    int selectionOffset = -1,
    int selectionLength = 0,
  }) {
    var selectionEnd = selectionOffset + selectionLength;
    var locator = NodeLocator(selectionOffset, selectionEnd);
    var node = locator.searchWithin(resolvedResult.unit);
    if (node == null) {
      return null;
    }

    return CorrectionProducerContext._(
      resolvedResult: resolvedResult,
      workspace: workspace,
      node: node,
      applyingBulkFixes: applyingBulkFixes,
      dartFixContext: dartFixContext,
      diagnostic: diagnostic,
      overrideSet: overrideSet,
      selectionOffset: selectionOffset,
      selectionLength: selectionLength,
    );
  }
}

abstract class CorrectionProducerWithDiagnostic extends CorrectionProducer {
  /// TODO(migration) Consider providing it via constructor.
  @override
  Diagnostic get diagnostic => super.diagnostic!;
}

/// An object that can dynamically compute multiple corrections (fixes or
/// assists).
abstract class MultiCorrectionProducer extends _AbstractCorrectionProducer {
  /// Return each of the individual producers generated by this producer.
  Iterable<CorrectionProducer> get producers;
}

/// An object that can compute a correction (fix or assist) in a Dart file.
abstract class SingleCorrectionProducer extends _AbstractCorrectionProducer {
  /// Return the arguments that should be used when composing the message for an
  /// assist, or `null` if the assist message has no parameters or if this
  /// producer doesn't support assists.
  List<Object>? get assistArguments => null;

  /// Return the assist kind that should be used to build an assist, or `null`
  /// if this producer doesn't support assists.
  AssistKind? get assistKind => null;

  /// Return `true` if this producer can be used to fix diagnostics across
  /// multiple files. Cases where this will return `false` include fixes for
  /// which
  /// - the modified regions can overlap, and
  /// - fixes that have not been tested to ensure that they can be used this
  ///   way.
  bool get canBeAppliedInBulk => false;

  /// Return `true` if this producer can be used to fix multiple diagnostics in
  /// the same file. Cases where this will return `false` include fixes for
  /// which
  /// - the modified regions can overlap,
  /// - the fix for one diagnostic would fix all diagnostics with the same code,
  ///   and,
  /// - fixes that have not been tested to ensure that they can be used this
  ///   way.
  ///
  /// Producers that return `true` should return non-null values from both
  /// [multiFixKind] and [multiFixArguments].
  bool get canBeAppliedToFile => false;

  /// Return the length of the error message being fixed, or `null` if there is
  /// no diagnostic.
  int? get errorLength => diagnostic?.problemMessage.length;

  /// Return the text of the error message being fixed, or `null` if there is
  /// no diagnostic.
  String? get errorMessage =>
      diagnostic?.problemMessage.messageText(includeUrl: true);

  /// Return the offset of the error message being fixed, or `null` if there is
  /// no diagnostic.
  int? get errorOffset => diagnostic?.problemMessage.offset;

  /// Return the arguments that should be used when composing the message for a
  /// fix, or `null` if the fix message has no parameters or if this producer
  /// doesn't support fixes.
  List<Object>? get fixArguments => null;

  /// Return the fix kind that should be used to build a fix, or `null` if this
  /// producer doesn't support fixes.
  FixKind? get fixKind => null;

  /// Return the arguments that should be used when composing the message for a
  /// multi-fix, or `null` if the fix message has no parameters or if this
  /// producer doesn't support multi-fixes.
  List<Object>? get multiFixArguments => null;

  /// Return the fix kind that should be used to build a multi-fix, or `null` if
  /// this producer doesn't support multi-fixes.
  FixKind? get multiFixKind => null;
}

/// The behavior shared by [CorrectionProducer] and [MultiCorrectionProducer].
abstract class _AbstractCorrectionProducer {
  /// The context used to produce corrections.
  /// TODO(migration) Make it not `late`, require in constructor.
  late CorrectionProducerContext _context;

  /// The most deeply nested node that completely covers the highlight region of
  /// the diagnostic, or `null` if there is no diagnostic, such a node does not
  /// exist, or if it hasn't been computed yet. Use [coveredNode] to access this
  /// field.
  AstNode? _coveredNode;

  /// Initialize a newly created producer.
  _AbstractCorrectionProducer();

  /// Return `true` if the fixes are being built for the bulk-fix request.
  bool get applyingBulkFixes => _context.applyingBulkFixes;

  /// The most deeply nested node that completely covers the highlight region of
  /// the diagnostic, or `null` if there is no diagnostic or if such a node does
  /// not exist.
  AstNode? get coveredNode {
    // TODO(brianwilkerson) Consider renaming this to `coveringNode`.
    if (_coveredNode == null) {
      final diagnostic = this.diagnostic;
      if (diagnostic == null) {
        return null;
      }
      var errorOffset = diagnostic.problemMessage.offset;
      var errorLength = diagnostic.problemMessage.length;
      _coveredNode =
          NodeLocator2(errorOffset, math.max(errorOffset + errorLength - 1, 0))
              .searchWithin(unit);
    }
    return _coveredNode;
  }

  /// Return the diagnostic being fixed, or `null` if this producer is being
  /// used to produce an assist.
  Diagnostic? get diagnostic => _context.diagnostic;

  /// Returns the EOL to use for this [CompilationUnit].
  String get eol => utils.endOfLine;

  /// Return the extension cache used to find available extensions.
  ExtensionCache get extensionCache => _context.dartFixContext!.extensionCache;

  String get file => _context.file;

  Flutter get flutter => Flutter.instance;

  /// Return the library element for the library in which a correction is being
  /// produced.
  LibraryElement get libraryElement => resolvedResult.libraryElement;

  AstNode get node => _context.node;

  /// Return the set of overrides to be applied to the transform set when
  /// running tests, or `null` if there are no overrides to apply.
  TransformOverrideSet? get overrideSet => _context.overrideSet;

  ResolvedUnitResult get resolvedResult => _context.resolvedResult;

  /// Return the resource provider used to access the file system.
  ResourceProvider get resourceProvider =>
      resolvedResult.session.resourceProvider;

  int get selectionEnd => _context.selectionEnd;

  int get selectionLength => _context.selectionLength;

  int get selectionOffset => _context.selectionOffset;

  AnalysisSessionHelper get sessionHelper => _context.sessionHelper;

  TypeProvider get typeProvider => _context.typeProvider;

  /// Return the type system appropriate to the library in which the correction
  /// was requested.
  TypeSystem get typeSystem => _context.resolvedResult.typeSystem;

  CompilationUnit get unit => _context.unit;

  CorrectionUtils get utils => _context.utils;

  /// Configure this producer based on the [context].
  void configure(CorrectionProducerContext context) {
    _context = context;
  }

  /// Return the text that should be displayed to users when referring to the
  /// given [type].
  String displayStringForType(DartType type) => type.getDisplayString(
      withNullability: libraryElement.isNonNullableByDefault);

  /// Return the function body of the most deeply nested method or function that
  /// encloses the [node], or `null` if the node is not in a method or function.
  FunctionBody? getEnclosingFunctionBody() {
    var closure = node.thisOrAncestorOfType<FunctionExpression>();
    if (closure != null) {
      return closure.body;
    }
    var function = node.thisOrAncestorOfType<FunctionDeclaration>();
    if (function != null) {
      return function.functionExpression.body;
    }
    var constructor = node.thisOrAncestorOfType<ConstructorDeclaration>();
    if (constructor != null) {
      return constructor.body;
    }
    var method = node.thisOrAncestorOfType<MethodDeclaration>();
    if (method != null) {
      return method.body;
    }
    return null;
  }

  /// Return the text of the given [range] in the unit.
  String getRangeText(SourceRange range) {
    return utils.getRangeText(range);
  }

  /// Return the top-level declarations with the [name] in libraries that are
  /// available to this context.
  List<TopLevelDeclaration> getTopLevelDeclarations(String name) =>
      _context.dartFixContext!.getTopLevelDeclarations(name);

  /// Return `true` the lint with the given [name] is enabled.
  bool isLintEnabled(String name) {
    return _context.isLintEnabled(name);
  }

  /// Return `true` if the selection covers an operator of the given
  /// [binaryExpression].
  bool isOperatorSelected(BinaryExpression binaryExpression) {
    AstNode left = binaryExpression.leftOperand;
    AstNode right = binaryExpression.rightOperand;
    // between the nodes
    if (selectionOffset >= left.end &&
        selectionOffset + selectionLength <= right.offset) {
      return true;
    }
    // or exactly select the node (but not with infix expressions)
    if (selectionOffset == left.offset &&
        selectionOffset + selectionLength == right.end) {
      if (left is BinaryExpression || right is BinaryExpression) {
        return false;
      }
      return true;
    }
    // invalid selection (part of node, etc)
    return false;
  }

  /// Return `true` if the given [node] is in a location where an implicit
  /// constructor invocation would be allowed.
  bool mightBeImplicitConstructor(AstNode node) {
    if (node is SimpleIdentifier) {
      var parent = node.parent;
      if (parent is MethodInvocation) {
        return parent.realTarget == null;
      }
    }
    return false;
  }

  /// Return `true` if the [node] might be a type name.
  bool mightBeTypeIdentifier(AstNode node) {
    if (node is SimpleIdentifier) {
      var parent = node.parent;
      if (parent is TypeName) {
        return true;
      }
      return _isNameOfType(node.name);
    }
    return false;
  }

  /// Replace all occurrences of the [oldIndent] with the [newIndent] within the
  /// [source].
  String replaceSourceIndent(
      String source, String oldIndent, String newIndent) {
    return source.replaceAll(RegExp('^$oldIndent', multiLine: true), newIndent);
  }

  /// Return `true` if the given [expression] should be wrapped with parenthesis
  /// when we want to use it as operand of a logical `and` expression.
  bool shouldWrapParenthesisBeforeAnd(Expression expression) {
    if (expression is BinaryExpression) {
      var binary = expression;
      var precedence = binary.operator.type.precedence;
      return precedence < TokenClass.LOGICAL_AND_OPERATOR.precedence;
    }
    return false;
  }

  /// Return `true` if the [name] is capitalized.
  bool _isNameOfType(String name) {
    if (name.isEmpty) {
      return false;
    }
    var firstLetter = name.substring(0, 1);
    if (firstLetter.toUpperCase() != firstLetter) {
      return false;
    }
    return true;
  }
}

extension DartFileEditBuilderExtension on DartFileEditBuilder {
  /// Add edits to the [builder] to remove any parentheses enclosing the
  /// [expression].
  // TODO(brianwilkerson) Consider moving this to DartFileEditBuilder.
  void removeEnclosingParentheses(Expression expression) {
    var precedence = getExpressionPrecedence(expression);
    while (expression.parent is ParenthesizedExpression) {
      var parenthesized = expression.parent as ParenthesizedExpression;
      if (getExpressionParentPrecedence(parenthesized) > precedence) {
        break;
      }
      addDeletion(range.token(parenthesized.leftParenthesis));
      addDeletion(range.token(parenthesized.rightParenthesis));
      expression = parenthesized;
    }
  }
}
