/**
 * @fileoverview A rule to control the use of single variable declarations.
 * @author Ian Christian Myers
 */

"use strict";

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

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

        docs: {
            description: "enforce variables to be declared either together or separately in functions",
            category: "Stylistic Issues",
            recommended: false,
            url: "https://eslint.org/docs/rules/one-var"
        },

        fixable: "code",

        schema: [
            {
                oneOf: [
                    {
                        enum: ["always", "never", "consecutive"]
                    },
                    {
                        type: "object",
                        properties: {
                            separateRequires: {
                                type: "boolean"
                            },
                            var: {
                                enum: ["always", "never", "consecutive"]
                            },
                            let: {
                                enum: ["always", "never", "consecutive"]
                            },
                            const: {
                                enum: ["always", "never", "consecutive"]
                            }
                        },
                        additionalProperties: false
                    },
                    {
                        type: "object",
                        properties: {
                            initialized: {
                                enum: ["always", "never", "consecutive"]
                            },
                            uninitialized: {
                                enum: ["always", "never", "consecutive"]
                            }
                        },
                        additionalProperties: false
                    }
                ]
            }
        ]
    },

    create(context) {
        const MODE_ALWAYS = "always";
        const MODE_NEVER = "never";
        const MODE_CONSECUTIVE = "consecutive";
        const mode = context.options[0] || MODE_ALWAYS;

        const options = {};

        if (typeof mode === "string") { // simple options configuration with just a string
            options.var = { uninitialized: mode, initialized: mode };
            options.let = { uninitialized: mode, initialized: mode };
            options.const = { uninitialized: mode, initialized: mode };
        } else if (typeof mode === "object") { // options configuration is an object
            options.separateRequires = !!mode.separateRequires;
            options.var = { uninitialized: mode.var, initialized: mode.var };
            options.let = { uninitialized: mode.let, initialized: mode.let };
            options.const = { uninitialized: mode.const, initialized: mode.const };
            if (Object.prototype.hasOwnProperty.call(mode, "uninitialized")) {
                options.var.uninitialized = mode.uninitialized;
                options.let.uninitialized = mode.uninitialized;
                options.const.uninitialized = mode.uninitialized;
            }
            if (Object.prototype.hasOwnProperty.call(mode, "initialized")) {
                options.var.initialized = mode.initialized;
                options.let.initialized = mode.initialized;
                options.const.initialized = mode.initialized;
            }
        }

        const sourceCode = context.getSourceCode();

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

        const functionStack = [];
        const blockStack = [];

        /**
         * Increments the blockStack counter.
         * @returns {void}
         * @private
         */
        function startBlock() {
            blockStack.push({
                let: { initialized: false, uninitialized: false },
                const: { initialized: false, uninitialized: false }
            });
        }

        /**
         * Increments the functionStack counter.
         * @returns {void}
         * @private
         */
        function startFunction() {
            functionStack.push({ initialized: false, uninitialized: false });
            startBlock();
        }

        /**
         * Decrements the blockStack counter.
         * @returns {void}
         * @private
         */
        function endBlock() {
            blockStack.pop();
        }

        /**
         * Decrements the functionStack counter.
         * @returns {void}
         * @private
         */
        function endFunction() {
            functionStack.pop();
            endBlock();
        }

        /**
         * Check if a variable declaration is a require.
         * @param {ASTNode} decl variable declaration Node
         * @returns {bool} if decl is a require, return true; else return false.
         * @private
         */
        function isRequire(decl) {
            return decl.init && decl.init.type === "CallExpression" && decl.init.callee.name === "require";
        }

        /**
         * Records whether initialized/uninitialized/required variables are defined in current scope.
         * @param {string} statementType node.kind, one of: "var", "let", or "const"
         * @param {ASTNode[]} declarations List of declarations
         * @param {Object} currentScope The scope being investigated
         * @returns {void}
         * @private
         */
        function recordTypes(statementType, declarations, currentScope) {
            for (let i = 0; i < declarations.length; i++) {
                if (declarations[i].init === null) {
                    if (options[statementType] && options[statementType].uninitialized === MODE_ALWAYS) {
                        currentScope.uninitialized = true;
                    }
                } else {
                    if (options[statementType] && options[statementType].initialized === MODE_ALWAYS) {
                        if (options.separateRequires && isRequire(declarations[i])) {
                            currentScope.required = true;
                        } else {
                            currentScope.initialized = true;
                        }
                    }
                }
            }
        }

        /**
         * Determines the current scope (function or block)
         * @param  {string} statementType node.kind, one of: "var", "let", or "const"
         * @returns {Object} The scope associated with statementType
         */
        function getCurrentScope(statementType) {
            let currentScope;

            if (statementType === "var") {
                currentScope = functionStack[functionStack.length - 1];
            } else if (statementType === "let") {
                currentScope = blockStack[blockStack.length - 1].let;
            } else if (statementType === "const") {
                currentScope = blockStack[blockStack.length - 1].const;
            }
            return currentScope;
        }

        /**
         * Counts the number of initialized and uninitialized declarations in a list of declarations
         * @param {ASTNode[]} declarations List of declarations
         * @returns {Object} Counts of 'uninitialized' and 'initialized' declarations
         * @private
         */
        function countDeclarations(declarations) {
            const counts = { uninitialized: 0, initialized: 0 };

            for (let i = 0; i < declarations.length; i++) {
                if (declarations[i].init === null) {
                    counts.uninitialized++;
                } else {
                    counts.initialized++;
                }
            }
            return counts;
        }

        /**
         * Determines if there is more than one var statement in the current scope.
         * @param {string} statementType node.kind, one of: "var", "let", or "const"
         * @param {ASTNode[]} declarations List of declarations
         * @returns {boolean} Returns true if it is the first var declaration, false if not.
         * @private
         */
        function hasOnlyOneStatement(statementType, declarations) {

            const declarationCounts = countDeclarations(declarations);
            const currentOptions = options[statementType] || {};
            const currentScope = getCurrentScope(statementType);
            const hasRequires = declarations.some(isRequire);

            if (currentOptions.uninitialized === MODE_ALWAYS && currentOptions.initialized === MODE_ALWAYS) {
                if (currentScope.uninitialized || currentScope.initialized) {
                    if (!hasRequires) {
                        return false;
                    }
                }
            }

            if (declarationCounts.uninitialized > 0) {
                if (currentOptions.uninitialized === MODE_ALWAYS && currentScope.uninitialized) {
                    return false;
                }
            }
            if (declarationCounts.initialized > 0) {
                if (currentOptions.initialized === MODE_ALWAYS && currentScope.initialized) {
                    if (!hasRequires) {
                        return false;
                    }
                }
            }
            if (currentScope.required && hasRequires) {
                return false;
            }
            recordTypes(statementType, declarations, currentScope);
            return true;
        }

        /**
         * Fixer to join VariableDeclaration's into a single declaration
         * @param   {VariableDeclarator[]} declarations The `VariableDeclaration` to join
         * @returns {Function}                         The fixer function
         */
        function joinDeclarations(declarations) {
            const declaration = declarations[0];
            const body = Array.isArray(declaration.parent.parent.body) ? declaration.parent.parent.body : [];
            const currentIndex = body.findIndex(node => node.range[0] === declaration.parent.range[0]);
            const previousNode = body[currentIndex - 1];

            return fixer => {
                const type = sourceCode.getTokenBefore(declaration);
                const prevSemi = sourceCode.getTokenBefore(type);
                const res = [];

                if (previousNode && previousNode.kind === sourceCode.getText(type)) {
                    if (prevSemi.value === ";") {
                        res.push(fixer.replaceText(prevSemi, ","));
                    } else {
                        res.push(fixer.insertTextAfter(prevSemi, ","));
                    }
                    res.push(fixer.replaceText(type, ""));
                }

                return res;
            };
        }

        /**
         * Fixer to split a VariableDeclaration into individual declarations
         * @param   {VariableDeclaration}   declaration The `VariableDeclaration` to split
         * @returns {Function}                          The fixer function
         */
        function splitDeclarations(declaration) {
            return fixer => declaration.declarations.map(declarator => {
                const tokenAfterDeclarator = sourceCode.getTokenAfter(declarator);

                if (tokenAfterDeclarator === null) {
                    return null;
                }

                const afterComma = sourceCode.getTokenAfter(tokenAfterDeclarator, { includeComments: true });

                if (tokenAfterDeclarator.value !== ",") {
                    return null;
                }

                /*
                 * `var x,y`
                 * tokenAfterDeclarator ^^ afterComma
                 */
                if (afterComma.range[0] === tokenAfterDeclarator.range[1]) {
                    return fixer.replaceText(tokenAfterDeclarator, `; ${declaration.kind} `);
                }

                /*
                 * `var x,
                 * tokenAfterDeclarator ^
                 *      y`
                 *      ^ afterComma
                 */
                if (
                    afterComma.loc.start.line > tokenAfterDeclarator.loc.end.line ||
                    afterComma.type === "Line" ||
                    afterComma.type === "Block"
                ) {
                    let lastComment = afterComma;

                    while (lastComment.type === "Line" || lastComment.type === "Block") {
                        lastComment = sourceCode.getTokenAfter(lastComment, { includeComments: true });
                    }

                    return fixer.replaceTextRange(
                        [tokenAfterDeclarator.range[0], lastComment.range[0]],
                        `;${sourceCode.text.slice(tokenAfterDeclarator.range[1], lastComment.range[0])}${declaration.kind} `
                    );
                }

                return fixer.replaceText(tokenAfterDeclarator, `; ${declaration.kind}`);
            }).filter(x => x);
        }

        /**
         * Checks a given VariableDeclaration node for errors.
         * @param {ASTNode} node The VariableDeclaration node to check
         * @returns {void}
         * @private
         */
        function checkVariableDeclaration(node) {
            const parent = node.parent;
            const type = node.kind;

            if (!options[type]) {
                return;
            }

            const declarations = node.declarations;
            const declarationCounts = countDeclarations(declarations);
            const mixedRequires = declarations.some(isRequire) && !declarations.every(isRequire);

            if (options[type].initialized === MODE_ALWAYS) {
                if (options.separateRequires && mixedRequires) {
                    context.report({
                        node,
                        message: "Split requires to be separated into a single block."
                    });
                }
            }

            // consecutive
            const nodeIndex = (parent.body && parent.body.length > 0 && parent.body.indexOf(node)) || 0;

            if (nodeIndex > 0) {
                const previousNode = parent.body[nodeIndex - 1];
                const isPreviousNodeDeclaration = previousNode.type === "VariableDeclaration";
                const declarationsWithPrevious = declarations.concat(previousNode.declarations || []);

                if (
                    isPreviousNodeDeclaration &&
                    previousNode.kind === type &&
                    !(declarationsWithPrevious.some(isRequire) && !declarationsWithPrevious.every(isRequire))
                ) {
                    const previousDeclCounts = countDeclarations(previousNode.declarations);

                    if (options[type].initialized === MODE_CONSECUTIVE && options[type].uninitialized === MODE_CONSECUTIVE) {
                        context.report({
                            node,
                            message: "Combine this with the previous '{{type}}' statement.",
                            data: {
                                type
                            },
                            fix: joinDeclarations(declarations)
                        });
                    } else if (options[type].initialized === MODE_CONSECUTIVE && declarationCounts.initialized > 0 && previousDeclCounts.initialized > 0) {
                        context.report({
                            node,
                            message: "Combine this with the previous '{{type}}' statement with initialized variables.",
                            data: {
                                type
                            },
                            fix: joinDeclarations(declarations)
                        });
                    } else if (options[type].uninitialized === MODE_CONSECUTIVE &&
                            declarationCounts.uninitialized > 0 &&
                            previousDeclCounts.uninitialized > 0) {
                        context.report({
                            node,
                            message: "Combine this with the previous '{{type}}' statement with uninitialized variables.",
                            data: {
                                type
                            },
                            fix: joinDeclarations(declarations)
                        });
                    }
                }
            }

            // always
            if (!hasOnlyOneStatement(type, declarations)) {
                if (options[type].initialized === MODE_ALWAYS && options[type].uninitialized === MODE_ALWAYS) {
                    context.report({
                        node,
                        message: "Combine this with the previous '{{type}}' statement.",
                        data: {
                            type
                        },
                        fix: joinDeclarations(declarations)
                    });
                } else {
                    if (options[type].initialized === MODE_ALWAYS && declarationCounts.initialized > 0) {
                        context.report({
                            node,
                            message: "Combine this with the previous '{{type}}' statement with initialized variables.",
                            data: {
                                type
                            },
                            fix: joinDeclarations(declarations)
                        });
                    }
                    if (options[type].uninitialized === MODE_ALWAYS && declarationCounts.uninitialized > 0) {
                        if (node.parent.left === node && (node.parent.type === "ForInStatement" || node.parent.type === "ForOfStatement")) {
                            return;
                        }
                        context.report({
                            node,
                            message: "Combine this with the previous '{{type}}' statement with uninitialized variables.",
                            data: {
                                type
                            },
                            fix: joinDeclarations(declarations)
                        });
                    }
                }
            }

            // never
            if (parent.type !== "ForStatement" || parent.init !== node) {
                const totalDeclarations = declarationCounts.uninitialized + declarationCounts.initialized;

                if (totalDeclarations > 1) {
                    if (options[type].initialized === MODE_NEVER && options[type].uninitialized === MODE_NEVER) {

                        // both initialized and uninitialized
                        context.report({
                            node,
                            message: "Split '{{type}}' declarations into multiple statements.",
                            data: {
                                type
                            },
                            fix: splitDeclarations(node)
                        });
                    } else if (options[type].initialized === MODE_NEVER && declarationCounts.initialized > 0) {

                        // initialized
                        context.report({
                            node,
                            message: "Split initialized '{{type}}' declarations into multiple statements.",
                            data: {
                                type
                            },
                            fix: splitDeclarations(node)
                        });
                    } else if (options[type].uninitialized === MODE_NEVER && declarationCounts.uninitialized > 0) {

                        // uninitialized
                        context.report({
                            node,
                            message: "Split uninitialized '{{type}}' declarations into multiple statements.",
                            data: {
                                type
                            },
                            fix: splitDeclarations(node)
                        });
                    }
                }
            }
        }

        //--------------------------------------------------------------------------
        // Public API
        //--------------------------------------------------------------------------

        return {
            Program: startFunction,
            FunctionDeclaration: startFunction,
            FunctionExpression: startFunction,
            ArrowFunctionExpression: startFunction,
            BlockStatement: startBlock,
            ForStatement: startBlock,
            ForInStatement: startBlock,
            ForOfStatement: startBlock,
            SwitchStatement: startBlock,
            VariableDeclaration: checkVariableDeclaration,
            "ForStatement:exit": endBlock,
            "ForOfStatement:exit": endBlock,
            "ForInStatement:exit": endBlock,
            "SwitchStatement:exit": endBlock,
            "BlockStatement:exit": endBlock,
            "Program:exit": endFunction,
            "FunctionDeclaration:exit": endFunction,
            "FunctionExpression:exit": endFunction,
            "ArrowFunctionExpression:exit": endFunction
        };

    }
};
