/**
 * @fileoverview Rule to flag statements that use != and == instead of !== and ===
 * @author Nicholas C. Zakas
 */

"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const astUtils = require("./utils/ast-utils");

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = {
    meta: {
        type: "suggestion",

        docs: {
            description: "require the use of `===` and `!==`",
            category: "Best Practices",
            recommended: false,
            url: "https://eslint.org/docs/rules/eqeqeq"
        },

        schema: {
            anyOf: [
                {
                    type: "array",
                    items: [
                        {
                            enum: ["always"]
                        },
                        {
                            type: "object",
                            properties: {
                                null: {
                                    enum: ["always", "never", "ignore"]
                                }
                            },
                            additionalProperties: false
                        }
                    ],
                    additionalItems: false
                },
                {
                    type: "array",
                    items: [
                        {
                            enum: ["smart", "allow-null"]
                        }
                    ],
                    additionalItems: false
                }
            ]
        },

        fixable: "code",

        messages: {
            unexpected: "Expected '{{expectedOperator}}' and instead saw '{{actualOperator}}'."
        }
    },

    create(context) {
        const config = context.options[0] || "always";
        const options = context.options[1] || {};
        const sourceCode = context.getSourceCode();

        const nullOption = (config === "always")
            ? options.null || "always"
            : "ignore";
        const enforceRuleForNull = (nullOption === "always");
        const enforceInverseRuleForNull = (nullOption === "never");

        /**
         * Checks if an expression is a typeof expression
         * @param  {ASTNode} node The node to check
         * @returns {boolean} if the node is a typeof expression
         */
        function isTypeOf(node) {
            return node.type === "UnaryExpression" && node.operator === "typeof";
        }

        /**
         * Checks if either operand of a binary expression is a typeof operation
         * @param {ASTNode} node The node to check
         * @returns {boolean} if one of the operands is typeof
         * @private
         */
        function isTypeOfBinary(node) {
            return isTypeOf(node.left) || isTypeOf(node.right);
        }

        /**
         * Checks if operands are literals of the same type (via typeof)
         * @param {ASTNode} node The node to check
         * @returns {boolean} if operands are of same type
         * @private
         */
        function areLiteralsAndSameType(node) {
            return node.left.type === "Literal" && node.right.type === "Literal" &&
                    typeof node.left.value === typeof node.right.value;
        }

        /**
         * Checks if one of the operands is a literal null
         * @param {ASTNode} node The node to check
         * @returns {boolean} if operands are null
         * @private
         */
        function isNullCheck(node) {
            return astUtils.isNullLiteral(node.right) || astUtils.isNullLiteral(node.left);
        }

        /**
         * Gets the location (line and column) of the binary expression's operator
         * @param {ASTNode} node The binary expression node to check
         * @returns {Object} { line, column } location of operator
         * @private
         */
        function getOperatorLocation(node) {
            const opToken = sourceCode.getTokenAfter(node.left);

            return { line: opToken.loc.start.line, column: opToken.loc.start.column };
        }

        /**
         * Reports a message for this rule.
         * @param {ASTNode} node The binary expression node that was checked
         * @param {string} expectedOperator The operator that was expected (either '==', '!=', '===', or '!==')
         * @returns {void}
         * @private
         */
        function report(node, expectedOperator) {
            context.report({
                node,
                loc: getOperatorLocation(node),
                messageId: "unexpected",
                data: { expectedOperator, actualOperator: node.operator },
                fix(fixer) {

                    // If the comparison is a `typeof` comparison or both sides are literals with the same type, then it's safe to fix.
                    if (isTypeOfBinary(node) || areLiteralsAndSameType(node)) {
                        const operatorToken = sourceCode.getFirstTokenBetween(
                            node.left,
                            node.right,
                            token => token.value === node.operator
                        );

                        return fixer.replaceText(operatorToken, expectedOperator);
                    }
                    return null;
                }
            });
        }

        return {
            BinaryExpression(node) {
                const isNull = isNullCheck(node);

                if (node.operator !== "==" && node.operator !== "!=") {
                    if (enforceInverseRuleForNull && isNull) {
                        report(node, node.operator.slice(0, -1));
                    }
                    return;
                }

                if (config === "smart" && (isTypeOfBinary(node) ||
                        areLiteralsAndSameType(node) || isNull)) {
                    return;
                }

                if (!enforceRuleForNull && isNull) {
                    return;
                }

                report(node, `${node.operator}=`);
            }
        };

    }
};
