/**
 * @fileoverview Rule to enforce consistent naming of "this" context variables
 * @author Raphael Pigulla
 */
"use strict";

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

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

        docs: {
            description: "enforce consistent naming when capturing the current execution context",
            category: "Stylistic Issues",
            recommended: false,
            url: "https://eslint.org/docs/rules/consistent-this"
        },

        schema: {
            type: "array",
            items: {
                type: "string",
                minLength: 1
            },
            uniqueItems: true
        },

        messages: {
            aliasNotAssignedToThis: "Designated alias '{{name}}' is not assigned to 'this'.",
            unexpectedAlias: "Unexpected alias '{{name}}' for 'this'."
        }
    },

    create(context) {
        let aliases = [];

        if (context.options.length === 0) {
            aliases.push("that");
        } else {
            aliases = context.options;
        }

        /**
         * Reports that a variable declarator or assignment expression is assigning
         * a non-'this' value to the specified alias.
         * @param {ASTNode} node - The assigning node.
         * @param {string}  name - the name of the alias that was incorrectly used.
         * @returns {void}
         */
        function reportBadAssignment(node, name) {
            context.report({ node, messageId: "aliasNotAssignedToThis", data: { name } });
        }

        /**
         * Checks that an assignment to an identifier only assigns 'this' to the
         * appropriate alias, and the alias is only assigned to 'this'.
         * @param {ASTNode} node - The assigning node.
         * @param {Identifier} name - The name of the variable assigned to.
         * @param {Expression} value - The value of the assignment.
         * @returns {void}
         */
        function checkAssignment(node, name, value) {
            const isThis = value.type === "ThisExpression";

            if (aliases.indexOf(name) !== -1) {
                if (!isThis || node.operator && node.operator !== "=") {
                    reportBadAssignment(node, name);
                }
            } else if (isThis) {
                context.report({ node, messageId: "unexpectedAlias", data: { name } });
            }
        }

        /**
         * Ensures that a variable declaration of the alias in a program or function
         * is assigned to the correct value.
         * @param {string} alias alias the check the assignment of.
         * @param {Object} scope scope of the current code we are checking.
         * @private
         * @returns {void}
         */
        function checkWasAssigned(alias, scope) {
            const variable = scope.set.get(alias);

            if (!variable) {
                return;
            }

            if (variable.defs.some(def => def.node.type === "VariableDeclarator" &&
                def.node.init !== null)) {
                return;
            }

            /*
             * The alias has been declared and not assigned: check it was
             * assigned later in the same scope.
             */
            if (!variable.references.some(reference => {
                const write = reference.writeExpr;

                return (
                    reference.from === scope &&
                    write && write.type === "ThisExpression" &&
                    write.parent.operator === "="
                );
            })) {
                variable.defs.map(def => def.node).forEach(node => {
                    reportBadAssignment(node, alias);
                });
            }
        }

        /**
         * Check each alias to ensure that is was assinged to the correct value.
         * @returns {void}
         */
        function ensureWasAssigned() {
            const scope = context.getScope();

            aliases.forEach(alias => {
                checkWasAssigned(alias, scope);
            });
        }

        return {
            "Program:exit": ensureWasAssigned,
            "FunctionExpression:exit": ensureWasAssigned,
            "FunctionDeclaration:exit": ensureWasAssigned,

            VariableDeclarator(node) {
                const id = node.id;
                const isDestructuring =
                    id.type === "ArrayPattern" || id.type === "ObjectPattern";

                if (node.init !== null && !isDestructuring) {
                    checkAssignment(node, id.name, node.init);
                }
            },

            AssignmentExpression(node) {
                if (node.left.type === "Identifier") {
                    checkAssignment(node, node.left.name, node.right);
                }
            }
        };

    }
};
