// 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.

// @dart = 2.9

import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';

class ConvertToContains extends CorrectionProducer {
  @override
  FixKind get fixKind => DartFixKind.CONVERT_TO_CONTAINS;

  @override
  FixKind get multiFixKind => DartFixKind.CONVERT_TO_CONTAINS_MULTI;

  @override
  Future<void> compute(ChangeBuilder builder) async {
    var comparison = node.thisOrAncestorOfType<BinaryExpression>();
    if (comparison == null) {
      return;
    }
    var leftOperand = comparison.leftOperand;
    var rightOperand = comparison.rightOperand;
    if (leftOperand is MethodInvocation && _isInteger(rightOperand)) {
      var value = _integerValue(rightOperand);
      var methodName = leftOperand.methodName;
      var deletionRange = range.endEnd(leftOperand, rightOperand);
      var notOffset = -1;
      var style = _negationStyle(comparison.operator.type, value);
      if (style == NegationStyle.none) {
        return;
      } else if (style == NegationStyle.negated) {
        notOffset = leftOperand.offset;
      }

      await builder.addDartFileEdit(file, (builder) {
        if (notOffset > 0) {
          builder.addSimpleInsertion(notOffset, '!');
        }
        builder.addSimpleReplacement(range.node(methodName), 'contains');
        builder.addDeletion(deletionRange);
      });
    } else if (_isInteger(leftOperand) && rightOperand is MethodInvocation) {
      var value = _integerValue(leftOperand);
      var methodName = rightOperand.methodName;
      var deletionRange = range.startStart(leftOperand, rightOperand);
      var notOffset = -1;
      var style =
          _negationStyle(_invertedTokenType(comparison.operator.type), value);
      if (style == NegationStyle.none) {
        return;
      } else if (style == NegationStyle.negated) {
        notOffset = rightOperand.offset;
      }

      await builder.addDartFileEdit(file, (builder) {
        builder.addDeletion(deletionRange);
        if (notOffset > 0) {
          builder.addSimpleInsertion(notOffset, '!');
        }
        builder.addSimpleReplacement(range.node(methodName), 'contains');
      });
    }
  }

  /// Return the value of the given [expression], given that [_isInteger]
  /// returned `true`.
  int _integerValue(Expression expression) {
    if (expression is IntegerLiteral) {
      return expression.value;
    } else if (expression is PrefixExpression &&
        expression.operator.type == TokenType.MINUS) {
      var operand = expression.operand;
      if (operand is IntegerLiteral) {
        return -operand.value;
      }
    }
    throw StateError('invalid integer value');
  }

  TokenType _invertedTokenType(TokenType type) {
    switch (type) {
      case TokenType.LT_EQ:
        return TokenType.GT_EQ;
      case TokenType.LT:
        return TokenType.GT;
      case TokenType.GT:
        return TokenType.LT;
      case TokenType.GT_EQ:
        return TokenType.LT_EQ;
      default:
        return type;
    }
  }

  /// Return `true` if the given [expression] is a literal integer, possibly
  /// prefixed by a negation operator.
  bool _isInteger(Expression expression) {
    return (expression is IntegerLiteral) ||
        (expression is PrefixExpression &&
            expression.operator.type == TokenType.MINUS &&
            expression.operand is IntegerLiteral);
  }

  NegationStyle _negationStyle(TokenType type, int value) {
    if (value == -1) {
      if (type == TokenType.EQ_EQ || type == TokenType.LT_EQ) {
        // `indexOf == -1` is the same as `!contains`
        // `indexOf <= -1` is the same as `!contains`
        return NegationStyle.negated;
      } else if (type == TokenType.BANG_EQ || type == TokenType.GT) {
        // `indexOf != -1` is the same as `contains`
        // `indexOf > -1` is the same as `contains`
        return NegationStyle.positive;
      } else if (type == TokenType.LT || type == TokenType.GT_EQ) {
        // `indexOf < -1` is always false
        // `indexOf >= -1` is always true
        return NegationStyle.none;
      }
    } else if (value == 0) {
      if (type == TokenType.GT_EQ) {
        // `indexOf >= 0` is the same as `contains`
        return NegationStyle.positive;
      } else if (type == TokenType.LT) {
        // `indexOf < 0` is the same as `!contains`
        return NegationStyle.negated;
      }
      // Any other comparison with zero should not have been flagged, so we
      // should never reach this point.
      return NegationStyle.none;
    } else if (value < -1) {
      // 'indexOf' is always >= -1, so comparing with lesser values makes
      // no sense.
      return NegationStyle.none;
    }
    // Comparison with any value greater than zero should not have been flagged,
    // so we should never reach this point.
    return NegationStyle.none;
  }

  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
  static ConvertToContains newInstance() => ConvertToContains();
}

/// An indication of whether the `contains` test should be negated, not negated,
/// or whether neither is appropriate and the code should be left unchanged.
enum NegationStyle { none, negated, positive }
