/**
 * @fileoverview Rule to disallow use of unmodified expressions in loop conditions
 * @author Toru Nagashima
 */

"use strict";

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

const Traverser = require("../shared/traverser"),
    astUtils = require("./utils/ast-utils");

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

const SENTINEL_PATTERN = /(?:(?:Call|Class|Function|Member|New|Yield)Expression|Statement|Declaration)$/u;
const LOOP_PATTERN = /^(?:DoWhile|For|While)Statement$/u; // for-in/of statements don't have `test` property.
const GROUP_PATTERN = /^(?:BinaryExpression|ConditionalExpression)$/u;
const SKIP_PATTERN = /^(?:ArrowFunction|Class|Function)Expression$/u;
const DYNAMIC_PATTERN = /^(?:Call|Member|New|TaggedTemplate|Yield)Expression$/u;

/**
 * @typedef {Object} LoopConditionInfo
 * @property {eslint-scope.Reference} reference - The reference.
 * @property {ASTNode} group - BinaryExpression or ConditionalExpression nodes
 *      that the reference is belonging to.
 * @property {Function} isInLoop - The predicate which checks a given reference
 *      is in this loop.
 * @property {boolean} modified - The flag that the reference is modified in
 *      this loop.
 */

/**
 * Checks whether or not a given reference is a write reference.
 *
 * @param {eslint-scope.Reference} reference - A reference to check.
 * @returns {boolean} `true` if the reference is a write reference.
 */
function isWriteReference(reference) {
    if (reference.init) {
        const def = reference.resolved && reference.resolved.defs[0];

        if (!def || def.type !== "Variable" || def.parent.kind !== "var") {
            return false;
        }
    }
    return reference.isWrite();
}

/**
 * Checks whether or not a given loop condition info does not have the modified
 * flag.
 *
 * @param {LoopConditionInfo} condition - A loop condition info to check.
 * @returns {boolean} `true` if the loop condition info is "unmodified".
 */
function isUnmodified(condition) {
    return !condition.modified;
}

/**
 * Checks whether or not a given loop condition info does not have the modified
 * flag and does not have the group this condition belongs to.
 *
 * @param {LoopConditionInfo} condition - A loop condition info to check.
 * @returns {boolean} `true` if the loop condition info is "unmodified".
 */
function isUnmodifiedAndNotBelongToGroup(condition) {
    return !(condition.modified || condition.group);
}

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

    return or[0] <= ir[0] && ir[1] <= or[1];
}

/**
 * Checks whether or not a given reference is inside of a loop node's condition.
 *
 * @param {ASTNode} node - A node to check.
 * @param {eslint-scope.Reference} reference - A reference to check.
 * @returns {boolean} `true` if the reference is inside of the loop node's
 *      condition.
 */
const isInLoop = {
    WhileStatement: isInRange,
    DoWhileStatement: isInRange,
    ForStatement(node, reference) {
        return (
            isInRange(node, reference) &&
            !(node.init && isInRange(node.init, reference))
        );
    }
};

/**
 * Gets the function which encloses a given reference.
 * This supports only FunctionDeclaration.
 *
 * @param {eslint-scope.Reference} reference - A reference to get.
 * @returns {ASTNode|null} The function node or null.
 */
function getEncloseFunctionDeclaration(reference) {
    let node = reference.identifier;

    while (node) {
        if (node.type === "FunctionDeclaration") {
            return node.id ? node : null;
        }

        node = node.parent;
    }

    return null;
}

/**
 * Updates the "modified" flags of given loop conditions with given modifiers.
 *
 * @param {LoopConditionInfo[]} conditions - The loop conditions to be updated.
 * @param {eslint-scope.Reference[]} modifiers - The references to update.
 * @returns {void}
 */
function updateModifiedFlag(conditions, modifiers) {

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

        for (let j = 0; !condition.modified && j < modifiers.length; ++j) {
            const modifier = modifiers[j];
            let funcNode, funcVar;

            /*
             * Besides checking for the condition being in the loop, we want to
             * check the function that this modifier is belonging to is called
             * in the loop.
             * FIXME: This should probably be extracted to a function.
             */
            const inLoop = condition.isInLoop(modifier) || Boolean(
                (funcNode = getEncloseFunctionDeclaration(modifier)) &&
                (funcVar = astUtils.getVariableByName(modifier.from.upper, funcNode.id.name)) &&
                funcVar.references.some(condition.isInLoop)
            );

            condition.modified = inLoop;
        }
    }
}

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

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

        docs: {
            description: "disallow unmodified loop conditions",
            category: "Best Practices",
            recommended: false,
            url: "https://eslint.org/docs/rules/no-unmodified-loop-condition"
        },

        schema: []
    },

    create(context) {
        const sourceCode = context.getSourceCode();
        let groupMap = null;

        /**
         * Reports a given condition info.
         *
         * @param {LoopConditionInfo} condition - A loop condition info to report.
         * @returns {void}
         */
        function report(condition) {
            const node = condition.reference.identifier;

            context.report({
                node,
                message: "'{{name}}' is not modified in this loop.",
                data: node
            });
        }

        /**
         * Registers given conditions to the group the condition belongs to.
         *
         * @param {LoopConditionInfo[]} conditions - A loop condition info to
         *      register.
         * @returns {void}
         */
        function registerConditionsToGroup(conditions) {
            for (let i = 0; i < conditions.length; ++i) {
                const condition = conditions[i];

                if (condition.group) {
                    let group = groupMap.get(condition.group);

                    if (!group) {
                        group = [];
                        groupMap.set(condition.group, group);
                    }
                    group.push(condition);
                }
            }
        }

        /**
         * Reports references which are inside of unmodified groups.
         *
         * @param {LoopConditionInfo[]} conditions - A loop condition info to report.
         * @returns {void}
         */
        function checkConditionsInGroup(conditions) {
            if (conditions.every(isUnmodified)) {
                conditions.forEach(report);
            }
        }

        /**
         * Checks whether or not a given group node has any dynamic elements.
         *
         * @param {ASTNode} root - A node to check.
         *      This node is one of BinaryExpression or ConditionalExpression.
         * @returns {boolean} `true` if the node is dynamic.
         */
        function hasDynamicExpressions(root) {
            let retv = false;

            Traverser.traverse(root, {
                visitorKeys: sourceCode.visitorKeys,
                enter(node) {
                    if (DYNAMIC_PATTERN.test(node.type)) {
                        retv = true;
                        this.break();
                    } else if (SKIP_PATTERN.test(node.type)) {
                        this.skip();
                    }
                }
            });

            return retv;
        }

        /**
         * Creates the loop condition information from a given reference.
         *
         * @param {eslint-scope.Reference} reference - A reference to create.
         * @returns {LoopConditionInfo|null} Created loop condition info, or null.
         */
        function toLoopCondition(reference) {
            if (reference.init) {
                return null;
            }

            let group = null;
            let child = reference.identifier;
            let node = child.parent;

            while (node) {
                if (SENTINEL_PATTERN.test(node.type)) {
                    if (LOOP_PATTERN.test(node.type) && node.test === child) {

                        // This reference is inside of a loop condition.
                        return {
                            reference,
                            group,
                            isInLoop: isInLoop[node.type].bind(null, node),
                            modified: false
                        };
                    }

                    // This reference is outside of a loop condition.
                    break;
                }

                /*
                 * If it's inside of a group, OK if either operand is modified.
                 * So stores the group this reference belongs to.
                 */
                if (GROUP_PATTERN.test(node.type)) {

                    // If this expression is dynamic, no need to check.
                    if (hasDynamicExpressions(node)) {
                        break;
                    } else {
                        group = node;
                    }
                }

                child = node;
                node = node.parent;
            }

            return null;
        }

        /**
         * Finds unmodified references which are inside of a loop condition.
         * Then reports the references which are outside of groups.
         *
         * @param {eslint-scope.Variable} variable - A variable to report.
         * @returns {void}
         */
        function checkReferences(variable) {

            // Gets references that exist in loop conditions.
            const conditions = variable
                .references
                .map(toLoopCondition)
                .filter(Boolean);

            if (conditions.length === 0) {
                return;
            }

            // Registers the conditions to belonging groups.
            registerConditionsToGroup(conditions);

            // Check the conditions are modified.
            const modifiers = variable.references.filter(isWriteReference);

            if (modifiers.length > 0) {
                updateModifiedFlag(conditions, modifiers);
            }

            /*
             * Reports the conditions which are not belonging to groups.
             * Others will be reported after all variables are done.
             */
            conditions
                .filter(isUnmodifiedAndNotBelongToGroup)
                .forEach(report);
        }

        return {
            "Program:exit"() {
                const queue = [context.getScope()];

                groupMap = new Map();

                let scope;

                while ((scope = queue.pop())) {
                    queue.push(...scope.childScopes);
                    scope.variables.forEach(checkReferences);
                }

                groupMap.forEach(checkConditionsInGroup);
                groupMap = null;
            }
        };
    }
};
