/**
 * @fileoverview Rule to replace assignment expressions with operator assignment
 * @author Brandon Mills
 */
"use strict";

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

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

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

/**
 * Checks whether an operator is commutative and has an operator assignment
 * shorthand form.
 * @param   {string}  operator Operator to check.
 * @returns {boolean}          True if the operator is commutative and has a
 *     shorthand form.
 */
function isCommutativeOperatorWithShorthand(operator) {
    return ["*", "&", "^", "|"].indexOf(operator) >= 0;
}

/**
 * Checks whether an operator is not commuatative and has an operator assignment
 * shorthand form.
 * @param   {string}  operator Operator to check.
 * @returns {boolean}          True if the operator is not commuatative and has
 *     a shorthand form.
 */
function isNonCommutativeOperatorWithShorthand(operator) {
    return ["+", "-", "/", "%", "<<", ">>", ">>>", "**"].indexOf(operator) >= 0;
}

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

/**
 * 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":

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

        default:
            return false;
    }
}

/**
 * Determines if the left side of a node can be safely fixed (i.e. if it activates the same getters/setters and)
 * toString calls regardless of whether assignment shorthand is used)
 * @param {ASTNode} node The node on the left side of the expression
 * @returns {boolean} `true` if the node can be fixed
 */
function canBeFixed(node) {
    return node.type === "Identifier" ||
        node.type === "MemberExpression" && node.object.type === "Identifier" && (!node.computed || node.property.type === "Literal");
}

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

        docs: {
            description: "require or disallow assignment operator shorthand where possible",
            category: "Stylistic Issues",
            recommended: false,
            url: "https://eslint.org/docs/rules/operator-assignment"
        },

        schema: [
            {
                enum: ["always", "never"]
            }
        ],

        fixable: "code",
        messages: {
            replaced: "Assignment can be replaced with operator assignment.",
            unexpected: "Unexpected operator assignment shorthand."
        }
    },

    create(context) {

        const sourceCode = context.getSourceCode();

        /**
         * Returns the operator token of an AssignmentExpression or BinaryExpression
         * @param {ASTNode} node An AssignmentExpression or BinaryExpression node
         * @returns {Token} The operator token in the node
         */
        function getOperatorToken(node) {
            return sourceCode.getFirstTokenBetween(node.left, node.right, token => token.value === node.operator);
        }

        /**
         * Ensures that an assignment uses the shorthand form where possible.
         * @param   {ASTNode} node An AssignmentExpression node.
         * @returns {void}
         */
        function verify(node) {
            if (node.operator !== "=" || node.right.type !== "BinaryExpression") {
                return;
            }

            const left = node.left;
            const expr = node.right;
            const operator = expr.operator;

            if (isCommutativeOperatorWithShorthand(operator) || isNonCommutativeOperatorWithShorthand(operator)) {
                if (same(left, expr.left)) {
                    context.report({
                        node,
                        messageId: "replaced",
                        fix(fixer) {
                            if (canBeFixed(left)) {
                                const equalsToken = getOperatorToken(node);
                                const operatorToken = getOperatorToken(expr);
                                const leftText = sourceCode.getText().slice(node.range[0], equalsToken.range[0]);
                                const rightText = sourceCode.getText().slice(operatorToken.range[1], node.right.range[1]);

                                return fixer.replaceText(node, `${leftText}${expr.operator}=${rightText}`);
                            }
                            return null;
                        }
                    });
                } else if (same(left, expr.right) && isCommutativeOperatorWithShorthand(operator)) {

                    /*
                     * This case can't be fixed safely.
                     * If `a` and `b` both have custom valueOf() behavior, then fixing `a = b * a` to `a *= b` would
                     * change the execution order of the valueOf() functions.
                     */
                    context.report({
                        node,
                        messageId: "replaced"
                    });
                }
            }
        }

        /**
         * Warns if an assignment expression uses operator assignment shorthand.
         * @param   {ASTNode} node An AssignmentExpression node.
         * @returns {void}
         */
        function prohibit(node) {
            if (node.operator !== "=") {
                context.report({
                    node,
                    messageId: "unexpected",
                    fix(fixer) {
                        if (canBeFixed(node.left)) {
                            const operatorToken = getOperatorToken(node);
                            const leftText = sourceCode.getText().slice(node.range[0], operatorToken.range[0]);
                            const newOperator = node.operator.slice(0, -1);
                            let rightText;

                            // If this change would modify precedence (e.g. `foo *= bar + 1` => `foo = foo * (bar + 1)`), parenthesize the right side.
                            if (
                                astUtils.getPrecedence(node.right) <= astUtils.getPrecedence({ type: "BinaryExpression", operator: newOperator }) &&
                                !astUtils.isParenthesised(sourceCode, node.right)
                            ) {
                                rightText = `${sourceCode.text.slice(operatorToken.range[1], node.right.range[0])}(${sourceCode.getText(node.right)})`;
                            } else {
                                rightText = sourceCode.text.slice(operatorToken.range[1], node.range[1]);
                            }

                            return fixer.replaceText(node, `${leftText}= ${leftText}${newOperator}${rightText}`);
                        }
                        return null;
                    }
                });
            }
        }

        return {
            AssignmentExpression: context.options[0] !== "never" ? verify : prohibit
        };

    }
};
