// Copyright (c) 2020, 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_provider.dart';
import 'package:analyzer/dart/element/type_system.dart';

/// Information about a method call that we might want to transform into its
/// "OrNull" counterpart.  See [WhereOrNullTransformer] for more information.
class WhereOrNullTransformationInfo {
  /// AST node of the method invocation.
  final MethodInvocation methodInvocation;

  /// AST node of the "orElse" argument of the method invocation.
  final NamedExpression orElseArgument;

  /// Original name of the method being called, prior to transformation.
  final String originalName;

  /// New method to call, after transformation.
  final String replacementName;

  WhereOrNullTransformationInfo(this.methodInvocation, this.orElseArgument,
      this.originalName, this.replacementName);
}

/// Methods to assist in transforming calls to the `Iterable` methods
/// `firstWhere`, `lastWhere`, and `singleWhere` into calls to the
/// `package:collection` methods `firstWhereOrNull`, `lastWhereOrNull`, or
/// `singleWhereOrNull`, where possible.
///
/// An example of the kind of code that can be transformed is:
///
///     int firstEven(Iterable<int> x)
///         => x.firstWhere((x) => x.isEven, orElse: () => null);
///
/// We transform this into:
///
///     int firstEven(Iterable<int> x)
///         => x.firstWhereOrNull((x) => x.isEven);
///
/// Without this transformation, the migrated result would have been:
///
///     int firstEven(Iterable<int?> x)
///         => x.firstWhere((x) => x.isEven, orElse: () => null);
///
/// Which would have placed an otherwise unnecessary nullability requirement on
/// the type argument of the type of `x`.
class WhereOrNullTransformer {
  static const _replacementNames = {
    'firstWhere': 'firstWhereOrNull',
    'lastWhere': 'lastWhereOrNull',
    'singleWhere': 'singleWhereOrNull'
  };

  final TypeProvider _typeProvider;

  final TypeSystem _typeSystem;

  WhereOrNullTransformer(this._typeProvider, this._typeSystem);

  /// If [expression] is the `orElse` argument of a call that can be
  /// transformed, returns information about the transformable call; otherwise
  /// returns `null`.
  WhereOrNullTransformationInfo tryTransformOrElseArgument(
          Expression expression) =>
      _tryTransformMethodInvocation(expression?.parent?.parent?.parent);

  /// Searches [argumentList] for a named argument with the name "orElse".  If
  /// such an argument is found, and no other named arguments are found, it is
  /// returned; otherwise `null` is returned.
  NamedExpression _findOrElseArgument(ArgumentList argumentList) {
    NamedExpression orElseArgument;
    for (var argument in argumentList.arguments) {
      if (argument is NamedExpression) {
        if (argument.name.label.name == 'orElse') {
          orElseArgument = argument;
        } else {
          // The presence of an unexpected named argument means the user is
          // calling their own override of the method, and presumably they are
          // using this named argument to trigger a special behavior of their
          // override.  So don't try to replace it.
          return null;
        }
      }
    }
    return orElseArgument;
  }

  /// Determines if [element] is a method that can be transformed; if it can,
  /// the name of the replacement is returned; otherwise, `null` is returned.
  String _getTransformableMethodReplacementName(Element element) {
    if (element is MethodElement) {
      if (element.isStatic) return null;
      var replacementName = _replacementNames[element.name];
      if (replacementName == null) return null;
      var enclosingElement = element.declaration.enclosingElement;
      if (enclosingElement is ClassElement) {
        // If the class is `Iterable` or a subtype of it, we consider the user
        // to be calling a transformable method.
        if (_typeSystem.isSubtypeOf(
            enclosingElement.thisType, _typeProvider.iterableDynamicType)) {
          return replacementName;
        }
      }
    }
    return null;
  }

  /// Checks whether [expression] is of the form `() => null`.
  bool _isClosureReturningNull(Expression expression) {
    if (expression is FunctionExpression) {
      if (expression.typeParameters != null) return false;
      if (expression.parameters.parameters.isNotEmpty) return false;
      var body = expression.body;
      if (body is ExpressionFunctionBody) {
        if (body.expression is NullLiteral) return true;
      }
    }
    return false;
  }

  /// If [node] is a call that can be transformed, returns information about the
  /// transformable call; otherwise returns `null`.
  WhereOrNullTransformationInfo _tryTransformMethodInvocation(AstNode node) {
    if (node is MethodInvocation) {
      var replacementName =
          _getTransformableMethodReplacementName(node.methodName.staticElement);
      if (replacementName == null) return null;
      var orElseArgument = _findOrElseArgument(node.argumentList);
      if (orElseArgument == null) return null;
      if (!_isClosureReturningNull(orElseArgument.expression)) return null;
      return WhereOrNullTransformationInfo(
          node, orElseArgument, node.methodName.name, replacementName);
    }
    return null;
  }
}
