// 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:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/services/linter/lint_names.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/source/source_range.dart';
import 'package:analyzer/src/dart/error/hint_codes.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 RemoveComparison extends CorrectionProducer {
  @override
  bool canBeAppliedInBulk;

  @override
  bool canBeAppliedToFile;

  RemoveComparison(this.canBeAppliedInBulk, this.canBeAppliedToFile);

  @override
  FixKind get fixKind => DartFixKind.REMOVE_COMPARISON;

  @override
  FixKind get multiFixKind => DartFixKind.REMOVE_COMPARISON_MULTI;

  /// Return `true` if the null comparison will always return `false`.
  bool get _conditionIsFalse =>
      (diagnostic as AnalysisError).errorCode ==
      HintCode.UNNECESSARY_NULL_COMPARISON_FALSE;

  /// Return `true` if the null comparison will always return `true`.
  bool get _conditionIsTrue {
    var errorCode = (diagnostic as AnalysisError).errorCode;
    return errorCode == HintCode.UNNECESSARY_NULL_COMPARISON_TRUE ||
        errorCode.name == LintNames.avoid_null_checks_in_equality_operators;
  }

  @override
  Future<void> compute(ChangeBuilder builder) async {
    var binaryExpression = node;
    if (binaryExpression is! BinaryExpression) {
      return;
    }
    var parent = binaryExpression.parent;
    if (parent is AssertInitializer && _conditionIsTrue) {
      var constructor = parent.parent as ConstructorDeclaration;
      var list = constructor.initializers;
      if (list.length == 1) {
        await builder.addDartFileEdit(file, (builder) {
          builder.addDeletion(range.endEnd(constructor.parameters, parent));
        });
      } else {
        await builder.addDartFileEdit(file, (builder) {
          builder.addDeletion(range.nodeInList(list, parent));
        });
      }
    } else if (parent is AssertStatement && _conditionIsTrue) {
      await builder.addDartFileEdit(file, (builder) {
        builder.addDeletion(utils.getLinesRange(range.node(parent)));
      });
    } else if (parent is BinaryExpression) {
      if (parent.operator.type == TokenType.AMPERSAND_AMPERSAND &&
          _conditionIsTrue) {
        await _removeOperatorAndOperand(builder, parent, binaryExpression);
      } else if (parent.operator.type == TokenType.BAR_BAR &&
          _conditionIsFalse) {
        await _removeOperatorAndOperand(builder, parent, binaryExpression);
      }
    } else if (parent is IfStatement) {
      if (parent.elseStatement == null && _conditionIsTrue) {
        await _ifStatement(parent, builder);
      }
    }
  }

  Future<void> _ifStatement(IfStatement node, ChangeBuilder builder) async {
    await builder.addDartFileEdit(file, (builder) {
      var nodeRange = utils.getLinesRangeStatements([node]);

      String bodyCode;
      var body = node.thenStatement;
      if (body is Block) {
        var statements = body.statements;
        if (statements.isEmpty) {
          builder.addDeletion(nodeRange);
          return;
        } else {
          bodyCode = utils.getRangeText(
            utils.getLinesRangeStatements(statements),
          );
        }
      } else {
        bodyCode = utils.getRangeText(
          utils.getLinesRangeStatements([body]),
        );
      }

      bodyCode = utils.indentSourceLeftRight(bodyCode);
      builder.addSimpleReplacement(nodeRange, bodyCode);
    });
  }

  /// Use the [builder] to add an edit to delete the operator and given
  /// [operand] from the [binary] expression.
  Future<void> _removeOperatorAndOperand(ChangeBuilder builder,
      BinaryExpression binary, Expression operand) async {
    SourceRange operatorAndOperand;
    if (binary.leftOperand == node) {
      operatorAndOperand = range.startStart(node, binary.rightOperand);
    } else {
      operatorAndOperand = range.endEnd(binary.leftOperand, node);
    }
    await builder.addDartFileEdit(file, (builder) {
      builder.addDeletion(operatorAndOperand);
    });
  }

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

  /// Return an instance of this class that can apply bulk and in-file fixes.
  /// Used as a tear-off in `FixProcessor`.
  static RemoveComparison newInstanceBulkFixable() =>
      RemoveComparison(true, true);
}
