/**
 * @fileoverview A rule to suggest using of const declaration for variables that are never reassigned after declared.
 * @author Toru Nagashima
 */

"use strict";

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

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

const PATTERN_TYPE = /^(?:.+?Pattern|RestElement|SpreadProperty|ExperimentalRestProperty|Property)$/u;
const DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|SwitchCase)$/u;
const DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)$/u;

/**
 * Checks whether a given node is located at `ForStatement.init` or not.
 *
 * @param {ASTNode} node - A node to check.
 * @returns {boolean} `true` if the node is located at `ForStatement.init`.
 */
function isInitOfForStatement(node) {
    return node.parent.type === "ForStatement" && node.parent.init === node;
}

/**
 * Checks whether a given Identifier node becomes a VariableDeclaration or not.
 *
 * @param {ASTNode} identifier - An Identifier node to check.
 * @returns {boolean} `true` if the node can become a VariableDeclaration.
 */
function canBecomeVariableDeclaration(identifier) {
    let node = identifier.parent;

    while (PATTERN_TYPE.test(node.type)) {
        node = node.parent;
    }

    return (
        node.type === "VariableDeclarator" ||
        (
            node.type === "AssignmentExpression" &&
            node.parent.type === "ExpressionStatement" &&
            DECLARATION_HOST_TYPE.test(node.parent.parent.type)
        )
    );
}

/**
 * Checks if an property or element is from outer scope or function parameters
 * in destructing pattern.
 *
 * @param {string} name - A variable name to be checked.
 * @param {eslint-scope.Scope} initScope - A scope to start find.
 * @returns {boolean} Indicates if the variable is from outer scope or function parameters.
 */
function isOuterVariableInDestructing(name, initScope) {

    if (initScope.through.find(ref => ref.resolved && ref.resolved.name === name)) {
        return true;
    }

    const variable = astUtils.getVariableByName(initScope, name);

    if (variable !== null) {
        return variable.defs.some(def => def.type === "Parameter");
    }

    return false;
}

/**
 * Gets the VariableDeclarator/AssignmentExpression node that a given reference
 * belongs to.
 * This is used to detect a mix of reassigned and never reassigned in a
 * destructuring.
 *
 * @param {eslint-scope.Reference} reference - A reference to get.
 * @returns {ASTNode|null} A VariableDeclarator/AssignmentExpression node or
 *      null.
 */
function getDestructuringHost(reference) {
    if (!reference.isWrite()) {
        return null;
    }
    let node = reference.identifier.parent;

    while (PATTERN_TYPE.test(node.type)) {
        node = node.parent;
    }

    if (!DESTRUCTURING_HOST_TYPE.test(node.type)) {
        return null;
    }
    return node;
}

/**
 * Determines if a destructuring assignment node contains
 * any MemberExpression nodes. This is used to determine if a
 * variable that is only written once using destructuring can be
 * safely converted into a const declaration.
 * @param {ASTNode} node The ObjectPattern or ArrayPattern node to check.
 * @returns {boolean} True if the destructuring pattern contains
 *      a MemberExpression, false if not.
 */
function hasMemberExpressionAssignment(node) {
    switch (node.type) {
        case "ObjectPattern":
            return node.properties.some(prop => {
                if (prop) {

                    /*
                     * Spread elements have an argument property while
                     * others have a value property. Because different
                     * parsers use different node types for spread elements,
                     * we just check if there is an argument property.
                     */
                    return hasMemberExpressionAssignment(prop.argument || prop.value);
                }

                return false;
            });

        case "ArrayPattern":
            return node.elements.some(element => {
                if (element) {
                    return hasMemberExpressionAssignment(element);
                }

                return false;
            });

        case "AssignmentPattern":
            return hasMemberExpressionAssignment(node.left);

        case "MemberExpression":
            return true;

        // no default
    }

    return false;
}

/**
 * Gets an identifier node of a given variable.
 *
 * If the initialization exists or one or more reading references exist before
 * the first assignment, the identifier node is the node of the declaration.
 * Otherwise, the identifier node is the node of the first assignment.
 *
 * If the variable should not change to const, this function returns null.
 * - If the variable is reassigned.
 * - If the variable is never initialized nor assigned.
 * - If the variable is initialized in a different scope from the declaration.
 * - If the unique assignment of the variable cannot change to a declaration.
 *   e.g. `if (a) b = 1` / `return (b = 1)`
 * - If the variable is declared in the global scope and `eslintUsed` is `true`.
 *   `/*exported foo` directive comment makes such variables. This rule does not
 *   warn such variables because this rule cannot distinguish whether the
 *   exported variables are reassigned or not.
 *
 * @param {eslint-scope.Variable} variable - A variable to get.
 * @param {boolean} ignoreReadBeforeAssign -
 *      The value of `ignoreReadBeforeAssign` option.
 * @returns {ASTNode|null}
 *      An Identifier node if the variable should change to const.
 *      Otherwise, null.
 */
function getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign) {
    if (variable.eslintUsed && variable.scope.type === "global") {
        return null;
    }

    // Finds the unique WriteReference.
    let writer = null;
    let isReadBeforeInit = false;
    const references = variable.references;

    for (let i = 0; i < references.length; ++i) {
        const reference = references[i];

        if (reference.isWrite()) {
            const isReassigned = (
                writer !== null &&
                writer.identifier !== reference.identifier
            );

            if (isReassigned) {
                return null;
            }

            const destructuringHost = getDestructuringHost(reference);

            if (destructuringHost !== null && destructuringHost.left !== void 0) {
                const leftNode = destructuringHost.left;
                let hasOuterVariables = false,
                    hasNonIdentifiers = false;

                if (leftNode.type === "ObjectPattern") {
                    const properties = leftNode.properties;

                    hasOuterVariables = properties
                        .filter(prop => prop.value)
                        .map(prop => prop.value.name)
                        .some(name => isOuterVariableInDestructing(name, variable.scope));

                    hasNonIdentifiers = hasMemberExpressionAssignment(leftNode);

                } else if (leftNode.type === "ArrayPattern") {
                    const elements = leftNode.elements;

                    hasOuterVariables = elements
                        .map(element => element && element.name)
                        .some(name => isOuterVariableInDestructing(name, variable.scope));

                    hasNonIdentifiers = hasMemberExpressionAssignment(leftNode);
                }

                if (hasOuterVariables || hasNonIdentifiers) {
                    return null;
                }

            }

            writer = reference;

        } else if (reference.isRead() && writer === null) {
            if (ignoreReadBeforeAssign) {
                return null;
            }
            isReadBeforeInit = true;
        }
    }

    /*
     * If the assignment is from a different scope, ignore it.
     * If the assignment cannot change to a declaration, ignore it.
     */
    const shouldBeConst = (
        writer !== null &&
        writer.from === variable.scope &&
        canBecomeVariableDeclaration(writer.identifier)
    );

    if (!shouldBeConst) {
        return null;
    }

    if (isReadBeforeInit) {
        return variable.defs[0].name;
    }

    return writer.identifier;
}

/**
 * Groups by the VariableDeclarator/AssignmentExpression node that each
 * reference of given variables belongs to.
 * This is used to detect a mix of reassigned and never reassigned in a
 * destructuring.
 *
 * @param {eslint-scope.Variable[]} variables - Variables to group by destructuring.
 * @param {boolean} ignoreReadBeforeAssign -
 *      The value of `ignoreReadBeforeAssign` option.
 * @returns {Map<ASTNode, ASTNode[]>} Grouped identifier nodes.
 */
function groupByDestructuring(variables, ignoreReadBeforeAssign) {
    const identifierMap = new Map();

    for (let i = 0; i < variables.length; ++i) {
        const variable = variables[i];
        const references = variable.references;
        const identifier = getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign);
        let prevId = null;

        for (let j = 0; j < references.length; ++j) {
            const reference = references[j];
            const id = reference.identifier;

            /*
             * Avoid counting a reference twice or more for default values of
             * destructuring.
             */
            if (id === prevId) {
                continue;
            }
            prevId = id;

            // Add the identifier node into the destructuring group.
            const group = getDestructuringHost(reference);

            if (group) {
                if (identifierMap.has(group)) {
                    identifierMap.get(group).push(identifier);
                } else {
                    identifierMap.set(group, [identifier]);
                }
            }
        }
    }

    return identifierMap;
}

/**
 * Finds the nearest parent of node with a given type.
 *
 * @param {ASTNode} node – The node to search from.
 * @param {string} type – The type field of the parent node.
 * @param {Function} shouldStop – a predicate that returns true if the traversal should stop, and false otherwise.
 * @returns {ASTNode} The closest ancestor with the specified type; null if no such ancestor exists.
 */
function findUp(node, type, shouldStop) {
    if (!node || shouldStop(node)) {
        return null;
    }
    if (node.type === type) {
        return node;
    }
    return findUp(node.parent, type, shouldStop);
}

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

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

        docs: {
            description: "require `const` declarations for variables that are never reassigned after declared",
            category: "ECMAScript 6",
            recommended: false,
            url: "https://eslint.org/docs/rules/prefer-const"
        },

        fixable: "code",

        schema: [
            {
                type: "object",
                properties: {
                    destructuring: { enum: ["any", "all"], default: "any" },
                    ignoreReadBeforeAssign: { type: "boolean", default: false }
                },
                additionalProperties: false
            }
        ],
        messages: {
            useConst: "'{{name}}' is never reassigned. Use 'const' instead."
        }
    },

    create(context) {
        const options = context.options[0] || {};
        const sourceCode = context.getSourceCode();
        const shouldMatchAnyDestructuredVariable = options.destructuring !== "all";
        const ignoreReadBeforeAssign = options.ignoreReadBeforeAssign === true;
        const variables = [];
        let reportCount = 0;
        let name = "";

        /**
         * Reports given identifier nodes if all of the nodes should be declared
         * as const.
         *
         * The argument 'nodes' is an array of Identifier nodes.
         * This node is the result of 'getIdentifierIfShouldBeConst()', so it's
         * nullable. In simple declaration or assignment cases, the length of
         * the array is 1. In destructuring cases, the length of the array can
         * be 2 or more.
         *
         * @param {(eslint-scope.Reference|null)[]} nodes -
         *      References which are grouped by destructuring to report.
         * @returns {void}
         */
        function checkGroup(nodes) {
            const nodesToReport = nodes.filter(Boolean);

            if (nodes.length && (shouldMatchAnyDestructuredVariable || nodesToReport.length === nodes.length)) {
                const varDeclParent = findUp(nodes[0], "VariableDeclaration", parentNode => parentNode.type.endsWith("Statement"));
                const isVarDecParentNull = varDeclParent === null;

                if (!isVarDecParentNull && varDeclParent.declarations.length > 0) {
                    const firstDeclaration = varDeclParent.declarations[0];

                    if (firstDeclaration.init) {
                        const firstDecParent = firstDeclaration.init.parent;

                        /*
                         * First we check the declaration type and then depending on
                         * if the type is a "VariableDeclarator" or its an "ObjectPattern"
                         * we compare the name from the first identifier, if the names are different
                         * we assign the new name and reset the count of reportCount and nodeCount in
                         * order to check each block for the number of reported errors and base our fix
                         * based on comparing nodes.length and nodesToReport.length.
                         */

                        if (firstDecParent.type === "VariableDeclarator") {

                            if (firstDecParent.id.name !== name) {
                                name = firstDecParent.id.name;
                                reportCount = 0;
                            }

                            if (firstDecParent.id.type === "ObjectPattern") {
                                if (firstDecParent.init.name !== name) {
                                    name = firstDecParent.init.name;
                                    reportCount = 0;
                                }
                            }
                        }
                    }
                }

                let shouldFix = varDeclParent &&

                    // Don't do a fix unless the variable is initialized (or it's in a for-in or for-of loop)
                    (varDeclParent.parent.type === "ForInStatement" || varDeclParent.parent.type === "ForOfStatement" || varDeclParent.declarations[0].init) &&

                    /*
                     * If options.destructuring is "all", then this warning will not occur unless
                     * every assignment in the destructuring should be const. In that case, it's safe
                     * to apply the fix.
                     */
                    nodesToReport.length === nodes.length;

                if (!isVarDecParentNull && varDeclParent.declarations && varDeclParent.declarations.length !== 1) {

                    if (varDeclParent && varDeclParent.declarations && varDeclParent.declarations.length >= 1) {

                        /*
                         * Add nodesToReport.length to a count, then comparing the count to the length
                         * of the declarations in the current block.
                         */

                        reportCount += nodesToReport.length;

                        shouldFix = shouldFix && (reportCount === varDeclParent.declarations.length);
                    }
                }

                nodesToReport.forEach(node => {
                    context.report({
                        node,
                        messageId: "useConst",
                        data: node,
                        fix: shouldFix ? fixer => fixer.replaceText(sourceCode.getFirstToken(varDeclParent), "const") : null
                    });
                });
            }
        }

        return {
            "Program:exit"() {
                groupByDestructuring(variables, ignoreReadBeforeAssign).forEach(checkGroup);
            },

            VariableDeclaration(node) {
                if (node.kind === "let" && !isInitOfForStatement(node)) {
                    variables.push(...context.getDeclaredVariables(node));
                }
            }
        };
    }
};
