/**
 * @fileoverview Rule to flag use of parseInt without a radix argument
 * @author James Allardice
 */

"use strict";

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

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

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

const MODE_ALWAYS = "always",
    MODE_AS_NEEDED = "as-needed";

/**
 * Checks whether a given variable is shadowed or not.
 *
 * @param {eslint-scope.Variable} variable - A variable to check.
 * @returns {boolean} `true` if the variable is shadowed.
 */
function isShadowed(variable) {
    return variable.defs.length >= 1;
}

/**
 * Checks whether a given node is a MemberExpression of `parseInt` method or not.
 *
 * @param {ASTNode} node - A node to check.
 * @returns {boolean} `true` if the node is a MemberExpression of `parseInt`
 *      method.
 */
function isParseIntMethod(node) {
    return (
        node.type === "MemberExpression" &&
        !node.computed &&
        node.property.type === "Identifier" &&
        node.property.name === "parseInt"
    );
}

/**
 * Checks whether a given node is a valid value of radix or not.
 *
 * The following values are invalid.
 *
 * - A literal except numbers.
 * - undefined.
 *
 * @param {ASTNode} radix - A node of radix to check.
 * @returns {boolean} `true` if the node is valid.
 */
function isValidRadix(radix) {
    return !(
        (radix.type === "Literal" && typeof radix.value !== "number") ||
        (radix.type === "Identifier" && radix.name === "undefined")
    );
}

/**
 * Checks whether a given node is a default value of radix or not.
 *
 * @param {ASTNode} radix - A node of radix to check.
 * @returns {boolean} `true` if the node is the literal node of `10`.
 */
function isDefaultRadix(radix) {
    return radix.type === "Literal" && radix.value === 10;
}

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

module.exports = {
    meta: {
        docs: {
            description: "enforce the consistent use of the radix argument when using `parseInt()`",
            category: "Best Practices",
            recommended: false,
            url: "https://eslint.org/docs/rules/radix"
        },

        schema: [
            {
                enum: ["always", "as-needed"]
            }
        ]
    },

    create(context) {
        const mode = context.options[0] || MODE_ALWAYS;

        /**
         * Checks the arguments of a given CallExpression node and reports it if it
         * offends this rule.
         *
         * @param {ASTNode} node - A CallExpression node to check.
         * @returns {void}
         */
        function checkArguments(node) {
            const args = node.arguments;

            switch (args.length) {
                case 0:
                    context.report({
                        node,
                        message: "Missing parameters."
                    });
                    break;

                case 1:
                    if (mode === MODE_ALWAYS) {
                        context.report({
                            node,
                            message: "Missing radix parameter."
                        });
                    }
                    break;

                default:
                    if (mode === MODE_AS_NEEDED && isDefaultRadix(args[1])) {
                        context.report({
                            node,
                            message: "Redundant radix parameter."
                        });
                    } else if (!isValidRadix(args[1])) {
                        context.report({
                            node,
                            message: "Invalid radix parameter."
                        });
                    }
                    break;
            }
        }

        return {
            "Program:exit"() {
                const scope = context.getScope();
                let variable;

                // Check `parseInt()`
                variable = astUtils.getVariableByName(scope, "parseInt");
                if (!isShadowed(variable)) {
                    variable.references.forEach(reference => {
                        const node = reference.identifier;

                        if (astUtils.isCallee(node)) {
                            checkArguments(node.parent);
                        }
                    });
                }

                // Check `Number.parseInt()`
                variable = astUtils.getVariableByName(scope, "Number");
                if (!isShadowed(variable)) {
                    variable.references.forEach(reference => {
                        const node = reference.identifier.parent;

                        if (isParseIntMethod(node) && astUtils.isCallee(node)) {
                            checkArguments(node.parent);
                        }
                    });
                }
            }
        };
    }
};
