/**
 * @fileoverview Rule to check for the usage of var.
 * @author Jamund Ferguson
 */

"use strict";

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

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

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

/**
 * Check whether a given variable is a global variable or not.
 * @param {eslint-scope.Variable} variable The variable to check.
 * @returns {boolean} `true` if the variable is a global variable.
 */
function isGlobal(variable) {
    return Boolean(variable.scope) && variable.scope.type === "global";
}

/**
 * Finds the nearest function scope or global scope walking up the scope
 * hierarchy.
 *
 * @param {eslint-scope.Scope} scope - The scope to traverse.
 * @returns {eslint-scope.Scope} a function scope or global scope containing the given
 *      scope.
 */
function getEnclosingFunctionScope(scope) {
    let currentScope = scope;

    while (currentScope.type !== "function" && currentScope.type !== "global") {
        currentScope = currentScope.upper;
    }
    return currentScope;
}

/**
 * Checks whether the given variable has any references from a more specific
 * function expression (i.e. a closure).
 *
 * @param {eslint-scope.Variable} variable - A variable to check.
 * @returns {boolean} `true` if the variable is used from a closure.
 */
function isReferencedInClosure(variable) {
    const enclosingFunctionScope = getEnclosingFunctionScope(variable.scope);

    return variable.references.some(reference =>
        getEnclosingFunctionScope(reference.from) !== enclosingFunctionScope);
}

/**
 * Checks whether the given node is the assignee of a loop.
 *
 * @param {ASTNode} node - A VariableDeclaration node to check.
 * @returns {boolean} `true` if the declaration is assigned as part of loop
 *      iteration.
 */
function isLoopAssignee(node) {
    return (node.parent.type === "ForOfStatement" || node.parent.type === "ForInStatement") &&
        node === node.parent.left;
}

/**
 * Checks whether the given variable declaration is immediately initialized.
 *
 * @param {ASTNode} node - A VariableDeclaration node to check.
 * @returns {boolean} `true` if the declaration has an initializer.
 */
function isDeclarationInitialized(node) {
    return node.declarations.every(declarator => declarator.init !== null);
}

const SCOPE_NODE_TYPE = /^(?:Program|BlockStatement|SwitchStatement|ForStatement|ForInStatement|ForOfStatement)$/;

/**
 * Gets the scope node which directly contains a given node.
 *
 * @param {ASTNode} node - A node to get. This is a `VariableDeclaration` or
 *      an `Identifier`.
 * @returns {ASTNode} A scope node. This is one of `Program`, `BlockStatement`,
 *      `SwitchStatement`, `ForStatement`, `ForInStatement`, and
 *      `ForOfStatement`.
 */
function getScopeNode(node) {
    for (let currentNode = node; currentNode; currentNode = currentNode.parent) {
        if (SCOPE_NODE_TYPE.test(currentNode.type)) {
            return currentNode;
        }
    }

    /* istanbul ignore next : unreachable */
    return null;
}

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

/**
 * Checks whether a given variable is used from outside of the specified scope.
 *
 * @param {ASTNode} scopeNode - A scope node to check.
 * @returns {Function} The predicate function which checks whether a given
 *      variable is used from outside of the specified scope.
 */
function isUsedFromOutsideOf(scopeNode) {

    /**
     * Checks whether a given reference is inside of the specified scope or not.
     *
     * @param {eslint-scope.Reference} reference - A reference to check.
     * @returns {boolean} `true` if the reference is inside of the specified
     *      scope.
     */
    function isOutsideOfScope(reference) {
        const scope = scopeNode.range;
        const id = reference.identifier.range;

        return id[0] < scope[0] || id[1] > scope[1];
    }

    return function(variable) {
        return variable.references.some(isOutsideOfScope);
    };
}

/**
 * Creates the predicate function which checks whether a variable has their references in TDZ.
 *
 * The predicate function would return `true`:
 *
 * - if a reference is before the declarator. E.g. (var a = b, b = 1;)(var {a = b, b} = {};)
 * - if a reference is in the expression of their default value.  E.g. (var {a = a} = {};)
 * - if a reference is in the expression of their initializer.  E.g. (var a = a;)
 *
 * @param {ASTNode} node - The initializer node of VariableDeclarator.
 * @returns {Function} The predicate function.
 * @private
 */
function hasReferenceInTDZ(node) {
    const initStart = node.range[0];
    const initEnd = node.range[1];

    return variable => {
        const id = variable.defs[0].name;
        const idStart = id.range[0];
        const defaultValue = (id.parent.type === "AssignmentPattern" ? id.parent.right : null);
        const defaultStart = defaultValue && defaultValue.range[0];
        const defaultEnd = defaultValue && defaultValue.range[1];

        return variable.references.some(reference => {
            const start = reference.identifier.range[0];
            const end = reference.identifier.range[1];

            return !reference.init && (
                start < idStart ||
                (defaultValue !== null && start >= defaultStart && end <= defaultEnd) ||
                (start >= initStart && end <= initEnd)
            );
        });
    };
}

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

module.exports = {
    meta: {
        docs: {
            description: "require `let` or `const` instead of `var`",
            category: "ECMAScript 6",
            recommended: false,
            url: "https://eslint.org/docs/rules/no-var"
        },

        schema: [],
        fixable: "code"
    },

    create(context) {
        const sourceCode = context.getSourceCode();

        /**
         * Checks whether the variables which are defined by the given declarator node have their references in TDZ.
         *
         * @param {ASTNode} declarator - The VariableDeclarator node to check.
         * @returns {boolean} `true` if one of the variables which are defined by the given declarator node have their references in TDZ.
         */
        function hasSelfReferenceInTDZ(declarator) {
            if (!declarator.init) {
                return false;
            }
            const variables = context.getDeclaredVariables(declarator);

            return variables.some(hasReferenceInTDZ(declarator.init));
        }

        /**
         * Checks whether it can fix a given variable declaration or not.
         * It cannot fix if the following cases:
         *
         * - A variable is a global variable.
         * - A variable is declared on a SwitchCase node.
         * - A variable is redeclared.
         * - A variable is used from outside the scope.
         * - A variable is used from a closure within a loop.
         * - A variable might be used before it is assigned within a loop.
         * - A variable might be used in TDZ.
         * - A variable is declared in statement position (e.g. a single-line `IfStatement`)
         *
         * ## A variable is declared on a SwitchCase node.
         *
         * If this rule modifies 'var' declarations on a SwitchCase node, it
         * would generate the warnings of 'no-case-declarations' rule. And the
         * 'eslint:recommended' preset includes 'no-case-declarations' rule, so
         * this rule doesn't modify those declarations.
         *
         * ## A variable is redeclared.
         *
         * The language spec disallows redeclarations of `let` declarations.
         * Those variables would cause syntax errors.
         *
         * ## A variable is used from outside the scope.
         *
         * The language spec disallows accesses from outside of the scope for
         * `let` declarations. Those variables would cause reference errors.
         *
         * ## A variable is used from a closure within a loop.
         *
         * A `var` declaration within a loop shares the same variable instance
         * across all loop iterations, while a `let` declaration creates a new
         * instance for each iteration. This means if a variable in a loop is
         * referenced by any closure, changing it from `var` to `let` would
         * change the behavior in a way that is generally unsafe.
         *
         * ## A variable might be used before it is assigned within a loop.
         *
         * Within a loop, a `let` declaration without an initializer will be
         * initialized to null, while a `var` declaration will retain its value
         * from the previous iteration, so it is only safe to change `var` to
         * `let` if we can statically determine that the variable is always
         * assigned a value before its first access in the loop body. To keep
         * the implementation simple, we only convert `var` to `let` within
         * loops when the variable is a loop assignee or the declaration has an
         * initializer.
         *
         * @param {ASTNode} node - A variable declaration node to check.
         * @returns {boolean} `true` if it can fix the node.
         */
        function canFix(node) {
            const variables = context.getDeclaredVariables(node);
            const scopeNode = getScopeNode(node);

            if (node.parent.type === "SwitchCase" ||
                node.declarations.some(hasSelfReferenceInTDZ) ||
                variables.some(isGlobal) ||
                variables.some(isRedeclared) ||
                variables.some(isUsedFromOutsideOf(scopeNode))
            ) {
                return false;
            }

            if (astUtils.isInLoop(node)) {
                if (variables.some(isReferencedInClosure)) {
                    return false;
                }
                if (!isLoopAssignee(node) && !isDeclarationInitialized(node)) {
                    return false;
                }
            }

            if (
                !isLoopAssignee(node) &&
                !(node.parent.type === "ForStatement" && node.parent.init === node) &&
                !astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)
            ) {

                // If the declaration is not in a block, e.g. `if (foo) var bar = 1;`, then it can't be fixed.
                return false;
            }

            return true;
        }

        /**
         * Reports a given variable declaration node.
         *
         * @param {ASTNode} node - A variable declaration node to report.
         * @returns {void}
         */
        function report(node) {
            const varToken = sourceCode.getFirstToken(node);

            context.report({
                node,
                message: "Unexpected var, use let or const instead.",

                fix(fixer) {
                    if (canFix(node)) {
                        return fixer.replaceText(varToken, "let");
                    }
                    return null;
                }
            });
        }

        return {
            "VariableDeclaration:exit"(node) {
                if (node.kind === "var") {
                    report(node);
                }
            }
        };
    }
};
