/**
 * @fileoverview Rule to require or disallow yoda comparisons
 * @author Nicholas C. Zakas
 */
"use strict";

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

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

//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------

/**
 * Determines whether an operator is a comparison operator.
 * @param {string} operator The operator to check.
 * @returns {boolean} Whether or not it is a comparison operator.
 */
function isComparisonOperator(operator) {
    return (/^(==|===|!=|!==|<|>|<=|>=)$/u).test(operator);
}

/**
 * Determines whether an operator is an equality operator.
 * @param {string} operator The operator to check.
 * @returns {boolean} Whether or not it is an equality operator.
 */
function isEqualityOperator(operator) {
    return (/^(==|===)$/u).test(operator);
}

/**
 * Determines whether an operator is one used in a range test.
 * Allowed operators are `<` and `<=`.
 * @param {string} operator The operator to check.
 * @returns {boolean} Whether the operator is used in range tests.
 */
function isRangeTestOperator(operator) {
    return ["<", "<="].indexOf(operator) >= 0;
}

/**
 * Determines whether a non-Literal node is a negative number that should be
 * treated as if it were a single Literal node.
 * @param {ASTNode} node Node to test.
 * @returns {boolean} True if the node is a negative number that looks like a
 *                    real literal and should be treated as such.
 */
function looksLikeLiteral(node) {
    return (node.type === "UnaryExpression" &&
        node.operator === "-" &&
        node.prefix &&
        node.argument.type === "Literal" &&
        typeof node.argument.value === "number");
}

/**
 * Attempts to derive a Literal node from nodes that are treated like literals.
 * @param {ASTNode} node Node to normalize.
 * @param {number} [defaultValue] The default value to be returned if the node
 *                                is not a Literal.
 * @returns {ASTNode} One of the following options.
 *  1. The original node if the node is already a Literal
 *  2. A normalized Literal node with the negative number as the value if the
 *     node represents a negative number literal.
 *  3. The Literal node which has the `defaultValue` argument if it exists.
 *  4. Otherwise `null`.
 */
function getNormalizedLiteral(node, defaultValue) {
    if (node.type === "Literal") {
        return node;
    }

    if (looksLikeLiteral(node)) {
        return {
            type: "Literal",
            value: -node.argument.value,
            raw: `-${node.argument.value}`
        };
    }

    if (defaultValue) {
        return {
            type: "Literal",
            value: defaultValue,
            raw: String(defaultValue)
        };
    }

    return null;
}

/**
 * Checks whether two expressions reference the same value. For example:
 *     a = a
 *     a.b = a.b
 *     a[0] = a[0]
 *     a['b'] = a['b']
 * @param   {ASTNode} a Left side of the comparison.
 * @param   {ASTNode} b Right side of the comparison.
 * @returns {boolean}   True if both sides match and reference the same value.
 */
function same(a, b) {
    if (a.type !== b.type) {
        return false;
    }

    switch (a.type) {
        case "Identifier":
            return a.name === b.name;

        case "Literal":
            return a.value === b.value;

        case "MemberExpression": {
            const nameA = astUtils.getStaticPropertyName(a);

            // x.y = x["y"]
            if (nameA) {
                return (
                    same(a.object, b.object) &&
                    nameA === astUtils.getStaticPropertyName(b)
                );
            }

            /*
             * x[0] = x[0]
             * x[y] = x[y]
             * x.y = x.y
             */
            return (
                a.computed === b.computed &&
                same(a.object, b.object) &&
                same(a.property, b.property)
            );
        }

        case "ThisExpression":
            return true;

        default:
            return false;
    }
}

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

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

        docs: {
            description: "require or disallow \"Yoda\" conditions",
            category: "Best Practices",
            recommended: false,
            url: "https://eslint.org/docs/rules/yoda"
        },

        schema: [
            {
                enum: ["always", "never"]
            },
            {
                type: "object",
                properties: {
                    exceptRange: {
                        type: "boolean",
                        default: false
                    },
                    onlyEquality: {
                        type: "boolean",
                        default: false
                    }
                },
                additionalProperties: false
            }
        ],

        fixable: "code",
        messages: {
            expected: "Expected literal to be on the {{expectedSide}} side of {{operator}}."
        }
    },

    create(context) {

        // Default to "never" (!always) if no option
        const always = (context.options[0] === "always");
        const exceptRange = (context.options[1] && context.options[1].exceptRange);
        const onlyEquality = (context.options[1] && context.options[1].onlyEquality);

        const sourceCode = context.getSourceCode();

        /**
         * Determines whether node represents a range test.
         * A range test is a "between" test like `(0 <= x && x < 1)` or an "outside"
         * test like `(x < 0 || 1 <= x)`. It must be wrapped in parentheses, and
         * both operators must be `<` or `<=`. Finally, the literal on the left side
         * must be less than or equal to the literal on the right side so that the
         * test makes any sense.
         * @param {ASTNode} node LogicalExpression node to test.
         * @returns {boolean} Whether node is a range test.
         */
        function isRangeTest(node) {
            const left = node.left,
                right = node.right;

            /**
             * Determines whether node is of the form `0 <= x && x < 1`.
             * @returns {boolean} Whether node is a "between" range test.
             */
            function isBetweenTest() {
                let leftLiteral, rightLiteral;

                return (node.operator === "&&" &&
                    (leftLiteral = getNormalizedLiteral(left.left)) &&
                    (rightLiteral = getNormalizedLiteral(right.right, Number.POSITIVE_INFINITY)) &&
                    leftLiteral.value <= rightLiteral.value &&
                    same(left.right, right.left));
            }

            /**
             * Determines whether node is of the form `x < 0 || 1 <= x`.
             * @returns {boolean} Whether node is an "outside" range test.
             */
            function isOutsideTest() {
                let leftLiteral, rightLiteral;

                return (node.operator === "||" &&
                    (leftLiteral = getNormalizedLiteral(left.right, Number.NEGATIVE_INFINITY)) &&
                    (rightLiteral = getNormalizedLiteral(right.left)) &&
                    leftLiteral.value <= rightLiteral.value &&
                    same(left.left, right.right));
            }

            /**
             * Determines whether node is wrapped in parentheses.
             * @returns {boolean} Whether node is preceded immediately by an open
             *                    paren token and followed immediately by a close
             *                    paren token.
             */
            function isParenWrapped() {
                return astUtils.isParenthesised(sourceCode, node);
            }

            return (node.type === "LogicalExpression" &&
                left.type === "BinaryExpression" &&
                right.type === "BinaryExpression" &&
                isRangeTestOperator(left.operator) &&
                isRangeTestOperator(right.operator) &&
                (isBetweenTest() || isOutsideTest()) &&
                isParenWrapped());
        }

        const OPERATOR_FLIP_MAP = {
            "===": "===",
            "!==": "!==",
            "==": "==",
            "!=": "!=",
            "<": ">",
            ">": "<",
            "<=": ">=",
            ">=": "<="
        };

        /**
         * Returns a string representation of a BinaryExpression node with its sides/operator flipped around.
         * @param {ASTNode} node The BinaryExpression node
         * @returns {string} A string representation of the node with the sides and operator flipped
         */
        function getFlippedString(node) {
            const operatorToken = sourceCode.getFirstTokenBetween(node.left, node.right, token => token.value === node.operator);
            const textBeforeOperator = sourceCode.getText().slice(sourceCode.getTokenBefore(operatorToken).range[1], operatorToken.range[0]);
            const textAfterOperator = sourceCode.getText().slice(operatorToken.range[1], sourceCode.getTokenAfter(operatorToken).range[0]);
            const leftText = sourceCode.getText().slice(node.range[0], sourceCode.getTokenBefore(operatorToken).range[1]);
            const rightText = sourceCode.getText().slice(sourceCode.getTokenAfter(operatorToken).range[0], node.range[1]);

            return rightText + textBeforeOperator + OPERATOR_FLIP_MAP[operatorToken.value] + textAfterOperator + leftText;
        }

        //--------------------------------------------------------------------------
        // Public
        //--------------------------------------------------------------------------

        return {
            BinaryExpression(node) {
                const expectedLiteral = always ? node.left : node.right;
                const expectedNonLiteral = always ? node.right : node.left;

                // If `expectedLiteral` is not a literal, and `expectedNonLiteral` is a literal, raise an error.
                if (
                    (expectedNonLiteral.type === "Literal" || looksLikeLiteral(expectedNonLiteral)) &&
                    !(expectedLiteral.type === "Literal" || looksLikeLiteral(expectedLiteral)) &&
                    !(!isEqualityOperator(node.operator) && onlyEquality) &&
                    isComparisonOperator(node.operator) &&
                    !(exceptRange && isRangeTest(context.getAncestors().pop()))
                ) {
                    context.report({
                        node,
                        messageId: "expected",
                        data: {
                            operator: node.operator,
                            expectedSide: always ? "left" : "right"
                        },
                        fix: fixer => fixer.replaceText(node, getFlippedString(node))
                    });
                }

            }
        };

    }
};
