// Copyright (c) 2017, 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 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:linter/src/analyzer.dart';
import 'package:linter/src/util/dart_type_utilities.dart';

const _desc = r"Don't check for null in custom == operators.";

const _details = r'''

**DON'T** check for null in custom == operators.

As null is a special type, no class can be equivalent to it.  Thus, it is
redundant to check whether the other instance is null. 

**BAD:**
```
class Person {
  final String name;

  @override
  operator ==(other) =>
      other != null && other is Person && name == other.name;
}
```

**GOOD:**
```
class Person {
  final String name;

  @override
  operator ==(other) => other is Person && name == other.name;
}
```

''';

bool _isComparingEquality(TokenType tokenType) =>
    tokenType == TokenType.BANG_EQ || tokenType == TokenType.EQ_EQ;

bool _isComparingParameterWithNull(BinaryExpression node, Element parameter) =>
    _isComparingEquality(node.operator.type) &&
    ((DartTypeUtilities.isNullLiteral(node.leftOperand) &&
            _isParameter(node.rightOperand, parameter)) ||
        (DartTypeUtilities.isNullLiteral(node.rightOperand) &&
            _isParameter(node.leftOperand, parameter)));

bool _isParameter(Expression expression, Element parameter) =>
    DartTypeUtilities.getCanonicalElementFromIdentifier(expression) ==
    parameter;

bool _isParameterWithQuestion(AstNode node, Element parameter) =>
    (node is PropertyAccess &&
        node.operator?.type == TokenType.QUESTION_PERIOD &&
        DartTypeUtilities.getCanonicalElementFromIdentifier(node.target) ==
            parameter) ||
    (node is MethodInvocation &&
        node.operator?.type == TokenType.QUESTION_PERIOD &&
        DartTypeUtilities.getCanonicalElementFromIdentifier(node.target) ==
            parameter);

bool _isParameterWithQuestionQuestion(
        BinaryExpression node, Element parameter) =>
    node.operator.type == TokenType.QUESTION_QUESTION &&
    _isParameter(node.leftOperand, parameter);

class AvoidNullChecksInEqualityOperators extends LintRule
    implements NodeLintRule {
  AvoidNullChecksInEqualityOperators()
      : super(
            name: 'avoid_null_checks_in_equality_operators',
            description: _desc,
            details: _details,
            group: Group.style);

  @override
  void registerNodeProcessors(
      NodeLintRegistry registry, LinterContext context) {
    final visitor = _Visitor(this);
    registry.addMethodDeclaration(this, visitor);
  }
}

class _Visitor extends SimpleAstVisitor<void> {
  final LintRule rule;

  _Visitor(this.rule);

  @override
  void visitMethodDeclaration(MethodDeclaration node) {
    final parameters = node.parameters?.parameters;
    if (node.name.token?.type == TokenType.EQ_EQ && parameters?.length == 1) {
      final parameter = DartTypeUtilities.getCanonicalElementFromIdentifier(
          parameters.first.identifier);
      bool checkIfParameterIsNull(AstNode node) =>
          _isParameterWithQuestion(node, parameter) ||
          (node is BinaryExpression &&
              (_isParameterWithQuestionQuestion(node, parameter) ||
                  _isComparingParameterWithNull(node, parameter)));

      DartTypeUtilities.traverseNodesInDFS(node.body)
          .where(checkIfParameterIsNull)
          .forEach(rule.reportLint);
    }
  }
}
