// Copyright (c) 2014, 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/ast/token.dart';

import 'argument_list_visitor.dart';
import 'rule/argument.dart';
import 'rule/rule.dart';
import 'source_visitor.dart';

/// Helper class for [SourceVisitor] that handles visiting and writing a
/// chained series of "selectors": method invocations, property accesses,
/// prefixed identifiers, index expressions, and null-assertion operators.
///
/// In the AST, selectors are nested bottom up such that this expression:
///
///     obj.a(1)[2].c(3)
///
/// Is structured like:
///
///           .c()
///           /  \
///          []   3
///         /  \
///       .a()  2
///       /  \
///     obj   1
///
/// This means visiting the AST from top down visits the selectors from right
/// to left. It's easier to format that if we organize them as a linear series
/// of selectors from left to right. Further, we want to organize it into a
/// two-tier hierarchy. We have an outer list of method calls and property
/// accesses. Then each of those may have one or more postfix selectors
/// attached: indexers, null-assertions, or invocations. This mirrors how they
/// are formatted.
class CallChainVisitor {
  final SourceVisitor _visitor;

  /// The initial target of the call chain.
  ///
  /// This may be any expression except [MethodInvocation], [PropertyAccess] or
  /// [PrefixedIdentifier].
  final Expression _target;

  /// The list of dotted names ([PropertyAccess] and [PrefixedIdentifier]) at
  /// the start of the call chain.
  ///
  /// This will be empty if the [_target] is not a [SimpleIdentifier].
  final List<_Selector> _properties;

  /// The mixed method calls and property accesses in the call chain in the
  /// order that they appear in the source reading from left to right.
  final List<_Selector> _calls;

  /// The method calls containing block function literals that break the method
  /// chain and escape its indentation.
  ///
  ///     receiver.a().b().c(() {
  ///       ;
  ///     }).d(() {
  ///       ;
  ///     }).e();
  ///
  /// Here, it will contain `c` and `d`.
  ///
  /// The block calls must be contiguous and must be a suffix of the list of
  /// calls (except for the one allowed hanging call). Otherwise, none of them
  /// are treated as block calls:
  ///
  ///     receiver
  ///         .a()
  ///         .b(() {
  ///           ;
  ///         })
  ///         .c(() {
  ///           ;
  ///         })
  ///         .d()
  ///         .e();
  final List<_MethodSelector>? _blockCalls;

  /// If there is one or more block calls and a single chained expression after
  /// that, this will be that expression.
  ///
  ///     receiver.a().b().c(() {
  ///       ;
  ///     }).d(() {
  ///       ;
  ///     }).e();
  ///
  /// We allow a single hanging call after the blocks because it will never
  /// need to split before its `.` and this accommodates the common pattern of
  /// a trailing `toList()` or `toSet()` after a series of higher-order methods
  /// on an iterable.
  final _Selector? _hangingCall;

  /// Whether or not a [Rule] is currently active for the call chain.
  bool _ruleEnabled = false;

  /// Whether or not the span wrapping the call chain is currently active.
  bool _spanEnded = false;

  /// After the properties are visited (if there are any), this will be the
  /// rule used to split between them.
  PositionalRule? _propertyRule;

  /// Creates a new call chain visitor for [visitor] for the method chain
  /// contained in [node].
  ///
  /// The [node] is the outermost expression containing the chained "."
  /// operators and must be a [MethodInvocation], [PropertyAccess] or
  /// [PrefixedIdentifier].
  factory CallChainVisitor(SourceVisitor visitor, Expression node) {
    // Flatten the call chain tree to a list of selectors with postfix
    // expressions.
    var calls = <_Selector>[];
    var target = _unwrapTarget(node, calls);

    // An expression that starts with a series of dotted names gets treated a
    // little specially. We don't force leading properties to split with the
    // rest of the chain. Allows code like:
    //
    //     address.street.number
    //       .toString()
    //       .length;
    var properties = <_Selector>[];
    if (_unwrapNullAssertion(target) is SimpleIdentifier) {
      properties = calls.takeWhile((call) => call.isProperty).toList();
    }

    calls.removeRange(0, properties.length);

    // Separate out the block calls, if there are any.
    List<_MethodSelector>? blockCalls;
    _Selector? hangingCall;

    var inBlockCalls = false;
    for (var call in calls) {
      if (call.isBlockCall(visitor)) {
        inBlockCalls = true;
        blockCalls ??= [];
        blockCalls.add(call as _MethodSelector);
      } else if (inBlockCalls) {
        // We found a non-block call after a block call.
        if (call == calls.last) {
          // It's the one allowed hanging one, so it's OK.
          hangingCall = call;
          break;
        }

        // Don't allow any of the calls to be block formatted.
        blockCalls = null;
        break;
      }
    }

    if (blockCalls != null) {
      for (var blockCall in blockCalls) {
        calls.remove(blockCall);
      }
    }

    if (hangingCall != null) {
      calls.remove(hangingCall);
    }

    return CallChainVisitor._(
        visitor, target, properties, calls, blockCalls, hangingCall);
  }

  CallChainVisitor._(this._visitor, this._target, this._properties, this._calls,
      this._blockCalls, this._hangingCall);

  /// Builds chunks for the call chain.
  ///
  /// If [unnest] is `false` than this will not close the expression nesting
  /// created for the call chain and the caller must end it. Used by cascades
  /// to force a cascade after a method chain to be more deeply nested than
  /// the methods.
  void visit({bool? unnest}) {
    unnest ??= true;

    _visitor.builder.nestExpression();

    // Try to keep the entire method invocation one line.
    _visitor.builder.startSpan();

    // If a split in the target expression forces the first `.` to split, then
    // start the rule now so that it surrounds the target.
    var splitOnTarget = _forcesSplit(_target);

    if (splitOnTarget) {
      if (_properties.length > 1) {
        _propertyRule = PositionalRule(null, 0, 0);
        _visitor.builder.startLazyRule(_propertyRule);
      } else {
        _enableRule(lazy: true);
      }
    }

    _visitor.visit(_target);

    // Leading properties split like positional arguments: either not at all,
    // before one ".", or before all of them.
    if (_properties.length == 1) {
      _visitor.soloZeroSplit();
      _properties.single.write(this);
    } else if (_properties.length > 1) {
      if (!splitOnTarget) {
        _propertyRule = PositionalRule(null, 0, 0);
        _visitor.builder.startRule(_propertyRule);
      }

      for (var property in _properties) {
        _propertyRule!.beforeArgument(_visitor.zeroSplit());
        property.write(this);
      }

      _visitor.builder.endRule();
    }

    // Indent any block arguments in the chain that don't get special formatting
    // below. Only do this if there is more than one argument to avoid spurious
    // indentation in cases like:
    //
    //     object.method(wrapper(() {
    //       body;
    //     });
    // TODO(rnystrom): Come up with a less arbitrary way to express this?
    if (_calls.length > 1) _visitor.builder.startBlockArgumentNesting();

    // The chain of calls splits atomically (either all or none). Any block
    // arguments inside them get indented to line up with the `.`.
    for (var call in _calls) {
      _enableRule();
      _visitor.zeroSplit();
      call.write(this);
    }

    if (_calls.length > 1) _visitor.builder.endBlockArgumentNesting();

    // If there are block calls, end the chain and write those without any
    // extra indentation.
    if (_blockCalls != null) {
      _enableRule();
      _visitor.zeroSplit();
      _disableRule();

      for (var blockCall in _blockCalls!) {
        blockCall.write(this);
      }

      // If there is a hanging call after the last block, write it without any
      // split before the ".".
      _hangingCall?.write(this);
    }

    _disableRule();
    _endSpan();

    if (unnest) _visitor.builder.unnest();
  }

  /// Returns `true` if the method chain should split if a split occurs inside
  /// [expression].
  ///
  /// In most cases, splitting in a method chain's target forces the chain to
  /// split too:
  ///
  ///      receiver(very, long, argument,
  ///              list)                    // <-- Split here...
  ///          .method();                   //     ...forces split here.
  ///
  /// However, if the target is a collection or function literal (or an
  /// argument list ending in one of those), we don't want to split:
  ///
  ///      receiver(inner(() {
  ///        ;
  ///      }).method();                     // <-- Unsplit.
  bool _forcesSplit(Expression expression) {
    // TODO(rnystrom): Other cases we may want to consider handling and
    // recursing into:
    // * The right operand in an infix operator call.
    // * The body of a `=>` function.

    // Unwrap parentheses.
    while (expression is ParenthesizedExpression) {
      expression = expression.expression;
    }

    // Don't split right after a collection literal.
    if (expression is ListLiteral) return false;
    if (expression is SetOrMapLiteral) return false;

    // Don't split right after a non-empty curly-bodied function.
    if (expression is FunctionExpression) {
      if (expression.body is! BlockFunctionBody) return false;

      return (expression.body as BlockFunctionBody).block.statements.isEmpty;
    }

    // If the expression ends in an argument list, base the splitting on the
    // last argument.
    ArgumentList? argumentList;
    if (expression is MethodInvocation) {
      argumentList = expression.argumentList;
    } else if (expression is InstanceCreationExpression) {
      argumentList = expression.argumentList;
    } else if (expression is FunctionExpressionInvocation) {
      argumentList = expression.argumentList;
    }

    // Any other kind of expression always splits.
    if (argumentList == null) return true;
    if (argumentList.arguments.isEmpty) return true;

    var argument = argumentList.arguments.last;

    // If the argument list has a trailing comma, treat it like a collection.
    if (_visitor.hasCommaAfter(argument)) return false;

    if (argument is NamedExpression) {
      argument = argument.expression;
    }

    // TODO(rnystrom): This logic is similar (but not identical) to
    // ArgumentListVisitor.hasBlockArguments. They overlap conceptually and
    // both have their own peculiar heuristics. It would be good to unify and
    // rationalize them.

    return _forcesSplit(argument);
  }

  /// Called when a [_MethodSelector] has written its name and is about to
  /// write the argument list.
  void _beforeMethodArguments(_MethodSelector selector) {
    // If we don't have any block calls, stop the rule after the last method
    // call name, but before its arguments. This allows unsplit chains where
    // the last argument list wraps, like:
    //
    //     foo().bar().baz(
    //         argument, list);
    if (_blockCalls == null && _calls.isNotEmpty && selector == _calls.last) {
      _disableRule();
    }

    // For a single method call on an identifier, stop the span before the
    // arguments to make it easier to keep the call name with the target. In
    // other words, prefer:
    //
    //     target.method(
    //         argument, list);
    //
    // Over:
    //
    //     target
    //         .method(argument, list);
    //
    // Alternatively, the way to think of this is try to avoid splitting on the
    // "." when calling a single method on a single name. This is especially
    // important because the identifier is often a library prefix, and splitting
    // there looks really odd.
    if (_properties.isEmpty &&
        _calls.length == 1 &&
        _blockCalls == null &&
        _target is SimpleIdentifier) {
      _endSpan();
    }
  }

  /// If a [Rule] for the method chain is currently active, ends it.
  void _disableRule() {
    if (_ruleEnabled == false) return;

    _visitor.builder.endRule();
    _ruleEnabled = false;
  }

  /// Creates a new method chain [Rule] if one is not already active.
  void _enableRule({bool lazy = false}) {
    if (_ruleEnabled) return;

    // If the properties split, force the calls to split too.
    var rule = Rule();
    _propertyRule?.setNamedArgsRule(rule);

    if (lazy) {
      _visitor.builder.startLazyRule(rule);
    } else {
      _visitor.builder.startRule(rule);
    }

    _ruleEnabled = true;
  }

  /// Ends the span wrapping the call chain if it hasn't ended already.
  void _endSpan() {
    if (_spanEnded) return;

    _visitor.builder.endSpan();
    _spanEnded = true;
  }
}

/// One "selector" in a method call chain.
///
/// Each selector is a method call or property access. It may be followed by
/// one or more postfix expressions, which can be index expressions or
/// null-assertion operators. These are not treated like their own selectors
/// because the formatter attaches them to the previous method call or property
/// access:
///
///     receiver
///         .method(arg)[index]
///         .another()!
///         .third();
abstract class _Selector {
  /// The series of index and/or null-assertion postfix selectors that follow
  /// and are attached to this one.
  ///
  /// Elements in this list will either be [IndexExpression] or
  /// [PostfixExpression].
  final List<Expression> _postfixes = [];

  /// Whether this selector is a property access as opposed to a method call.
  bool get isProperty => true;

  /// Whether this selector is a method call whose arguments are block
  /// formatted.
  bool isBlockCall(SourceVisitor visitor) => false;

  /// Write the selector portion of the expression wrapped by this [_Selector]
  /// using [visitor], followed by any postfix selectors.
  void write(CallChainVisitor visitor) {
    writeSelector(visitor);

    // Write any trailing index and null-assertion operators.
    visitor._visitor.builder.nestExpression();
    for (var postfix in _postfixes) {
      if (postfix is FunctionExpressionInvocation) {
        // Allow splitting between the invocations if needed.
        visitor._visitor.soloZeroSplit();

        visitor._visitor.visit(postfix.typeArguments);
        visitor._visitor.visitArgumentList(postfix.argumentList);
      } else if (postfix is IndexExpression) {
        visitor._visitor.finishIndexExpression(postfix);
      } else if (postfix is PostfixExpression) {
        assert(postfix.operator.type == TokenType.BANG);
        visitor._visitor.token(postfix.operator);
      } else {
        // Unexpected type.
        assert(false);
      }
    }
    visitor._visitor.builder.unnest();
  }

  /// Subclasses implement this to write their selector.
  void writeSelector(CallChainVisitor visitor);
}

class _MethodSelector extends _Selector {
  final MethodInvocation _node;

  _MethodSelector(this._node);

  @override
  bool get isProperty => false;

  @override
  bool isBlockCall(SourceVisitor visitor) =>
      ArgumentListVisitor(visitor, _node.argumentList).hasBlockArguments;

  @override
  void writeSelector(CallChainVisitor visitor) {
    visitor._visitor.token(_node.operator);
    visitor._visitor.token(_node.methodName.token);

    visitor._beforeMethodArguments(this);

    visitor._visitor.builder.nestExpression();
    visitor._visitor.visit(_node.typeArguments);
    visitor._visitor
        .visitArgumentList(_node.argumentList, nestExpression: false);
    visitor._visitor.builder.unnest();
  }
}

class _PrefixedSelector extends _Selector {
  final PrefixedIdentifier _node;

  _PrefixedSelector(this._node);

  @override
  void writeSelector(CallChainVisitor visitor) {
    visitor._visitor.token(_node.period);
    visitor._visitor.visit(_node.identifier);
  }
}

class _PropertySelector extends _Selector {
  final PropertyAccess _node;

  _PropertySelector(this._node);

  @override
  void writeSelector(CallChainVisitor visitor) {
    visitor._visitor.token(_node.operator);
    visitor._visitor.visit(_node.propertyName);
  }
}

/// If [expression] is a null-assertion operator, returns its operand.
Expression _unwrapNullAssertion(Expression expression) {
  if (expression is PostfixExpression &&
      expression.operator.type == TokenType.BANG) {
    return expression.operand;
  }

  return expression;
}

/// Given [node], which is the outermost expression for some call chain,
/// recursively traverses the selectors to fill in the list of [calls].
///
/// Returns the remaining target expression that precedes the method chain.
/// For example, given:
///
///     foo.bar()!.baz[0][1].bang()
///
/// This returns `foo` and fills calls with:
///
///     selector  postfixes
///     --------  ---------
///     .bar()    !
///     .baz      [0], [1]
///     .bang()
Expression _unwrapTarget(Expression node, List<_Selector> calls) {
  // Don't include things that look like static method or constructor
  // calls in the call chain because that tends to split up named
  // constructors from their class.
  if (SourceVisitor.looksLikeStaticCall(node)) return node;

  // Selectors.
  if (node is MethodInvocation && node.target != null) {
    return _unwrapSelector(node.target!, _MethodSelector(node), calls);
  }

  if (node is PropertyAccess && node.target != null) {
    return _unwrapSelector(node.target!, _PropertySelector(node), calls);
  }

  if (node is PrefixedIdentifier) {
    return _unwrapSelector(node.prefix, _PrefixedSelector(node), calls);
  }

  // Postfix expressions.
  if (node is IndexExpression) {
    return _unwrapPostfix(node, node.target!, calls);
  }

  if (node is FunctionExpressionInvocation) {
    return _unwrapPostfix(node, node.function, calls);
  }

  if (node is PostfixExpression && node.operator.type == TokenType.BANG) {
    return _unwrapPostfix(node, node.operand, calls);
  }

  // Otherwise, it isn't a selector so we're done.
  return node;
}

Expression _unwrapPostfix(
    Expression node, Expression target, List<_Selector> calls) {
  target = _unwrapTarget(target, calls);

  // If we don't have a preceding selector to hang the postfix expression off
  // of, don't unwrap it and leave it attached to the target expression. For
  // example:
  //
  //     (list + another)[index]
  if (calls.isEmpty) return node;

  calls.last._postfixes.add(node);
  return target;
}

Expression _unwrapSelector(
    Expression target, _Selector selector, List<_Selector> calls) {
  target = _unwrapTarget(target, calls);
  calls.add(selector);
  return target;
}
