// 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);
    node ??= resolvedResult.unit;

    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.
  Stream<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 NamedType) {
        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;
    }
  }
}
