/**
 * @fileoverview Rule to flag when the same variable is declared more then once.
 * @author Ilya Volodin
 */

"use strict";

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

module.exports = {
    meta: {
        docs: {
            description: "disallow variable redeclaration",
            category: "Best Practices",
            recommended: true,
            url: "https://eslint.org/docs/rules/no-redeclare"
        },

        schema: [
            {
                type: "object",
                properties: {
                    builtinGlobals: { type: "boolean" }
                },
                additionalProperties: false
            }
        ]
    },

    create(context) {
        const options = {
            builtinGlobals: Boolean(context.options[0] && context.options[0].builtinGlobals)
        };

        /**
         * Find variables in a given scope and flag redeclared ones.
         * @param {Scope} scope - An eslint-scope scope object.
         * @returns {void}
         * @private
         */
        function findVariablesInScope(scope) {
            scope.variables.forEach(variable => {
                const hasBuiltin = options.builtinGlobals && "writeable" in variable;
                const count = (hasBuiltin ? 1 : 0) + variable.identifiers.length;

                if (count >= 2) {
                    variable.identifiers.sort((a, b) => a.range[1] - b.range[1]);

                    for (let i = (hasBuiltin ? 0 : 1), l = variable.identifiers.length; i < l; i++) {
                        context.report({ node: variable.identifiers[i], message: "'{{a}}' is already defined.", data: { a: variable.name } });
                    }
                }
            });

        }

        /**
         * Find variables in the current scope.
         * @param {ASTNode} node - The Program node.
         * @returns {void}
         * @private
         */
        function checkForGlobal(node) {
            const scope = context.getScope(),
                parserOptions = context.parserOptions,
                ecmaFeatures = parserOptions.ecmaFeatures || {};

            // Nodejs env or modules has a special scope.
            if (ecmaFeatures.globalReturn || node.sourceType === "module") {
                findVariablesInScope(scope.childScopes[0]);
            } else {
                findVariablesInScope(scope);
            }
        }

        /**
         * Find variables in the current scope.
         * @returns {void}
         * @private
         */
        function checkForBlock() {
            findVariablesInScope(context.getScope());
        }

        if (context.parserOptions.ecmaVersion >= 6) {
            return {
                Program: checkForGlobal,
                BlockStatement: checkForBlock,
                SwitchStatement: checkForBlock
            };
        }
        return {
            Program: checkForGlobal,
            FunctionDeclaration: checkForBlock,
            FunctionExpression: checkForBlock,
            ArrowFunctionExpression: checkForBlock
        };

    }
};
