/**
 * @fileoverview Rule to flag non-matching identifiers
 * @author Matthieu Larcher
 */

"use strict";

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

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

        docs: {
            description: "require identifiers to match a specified regular expression",
            category: "Stylistic Issues",
            recommended: false,
            url: "https://eslint.org/docs/rules/id-match"
        },

        schema: [
            {
                type: "string"
            },
            {
                type: "object",
                properties: {
                    properties: {
                        type: "boolean",
                        default: false
                    },
                    onlyDeclarations: {
                        type: "boolean",
                        default: false
                    },
                    ignoreDestructuring: {
                        type: "boolean",
                        default: false
                    }
                }
            }
        ],
        messages: {
            notMatch: "Identifier '{{name}}' does not match the pattern '{{pattern}}'."
        }
    },

    create(context) {

        //--------------------------------------------------------------------------
        // Options
        //--------------------------------------------------------------------------
        const pattern = context.options[0] || "^.+$",
            regexp = new RegExp(pattern, "u");

        const options = context.options[1] || {},
            properties = !!options.properties,
            onlyDeclarations = !!options.onlyDeclarations,
            ignoreDestructuring = !!options.ignoreDestructuring;

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

        // contains reported nodes to avoid reporting twice on destructuring with shorthand notation
        const reported = new Map();
        const ALLOWED_PARENT_TYPES = new Set(["CallExpression", "NewExpression"]);
        const DECLARATION_TYPES = new Set(["FunctionDeclaration", "VariableDeclarator"]);
        const IMPORT_TYPES = new Set(["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"]);

        /**
         * Checks if a string matches the provided pattern
         * @param {string} name The string to check.
         * @returns {boolean} if the string is a match
         * @private
         */
        function isInvalid(name) {
            return !regexp.test(name);
        }

        /**
         * Checks if a parent of a node is an ObjectPattern.
         * @param {ASTNode} node The node to check.
         * @returns {boolean} if the node is inside an ObjectPattern
         * @private
         */
        function isInsideObjectPattern(node) {
            let { parent } = node;

            while (parent) {
                if (parent.type === "ObjectPattern") {
                    return true;
                }

                parent = parent.parent;
            }

            return false;
        }

        /**
         * Verifies if we should report an error or not based on the effective
         * parent node and the identifier name.
         * @param {ASTNode} effectiveParent The effective parent node of the node to be reported
         * @param {string} name The identifier name of the identifier node
         * @returns {boolean} whether an error should be reported or not
         */
        function shouldReport(effectiveParent, name) {
            return (!onlyDeclarations || DECLARATION_TYPES.has(effectiveParent.type)) &&
                !ALLOWED_PARENT_TYPES.has(effectiveParent.type) && isInvalid(name);
        }

        /**
         * Reports an AST node as a rule violation.
         * @param {ASTNode} node The node to report.
         * @returns {void}
         * @private
         */
        function report(node) {
            if (!reported.has(node)) {
                context.report({
                    node,
                    messageId: "notMatch",
                    data: {
                        name: node.name,
                        pattern
                    }
                });
                reported.set(node, true);
            }
        }

        return {

            Identifier(node) {
                const name = node.name,
                    parent = node.parent,
                    effectiveParent = (parent.type === "MemberExpression") ? parent.parent : parent;

                if (parent.type === "MemberExpression") {

                    if (!properties) {
                        return;
                    }

                    // Always check object names
                    if (parent.object.type === "Identifier" &&
                        parent.object.name === name) {
                        if (isInvalid(name)) {
                            report(node);
                        }

                    // Report AssignmentExpressions left side's assigned variable id
                    } else if (effectiveParent.type === "AssignmentExpression" &&
                        effectiveParent.left.type === "MemberExpression" &&
                        effectiveParent.left.property.name === node.name) {
                        if (isInvalid(name)) {
                            report(node);
                        }

                    // Report AssignmentExpressions only if they are the left side of the assignment
                    } else if (effectiveParent.type === "AssignmentExpression" && effectiveParent.right.type !== "MemberExpression") {
                        if (isInvalid(name)) {
                            report(node);
                        }
                    }

                /*
                 * Properties have their own rules, and
                 * AssignmentPattern nodes can be treated like Properties:
                 * e.g.: const { no_camelcased = false } = bar;
                 */
                } else if (parent.type === "Property" || parent.type === "AssignmentPattern") {

                    if (parent.parent && parent.parent.type === "ObjectPattern") {
                        if (parent.shorthand && parent.value.left && isInvalid(name)) {

                            report(node);
                        }

                        const assignmentKeyEqualsValue = parent.key.name === parent.value.name;

                        // prevent checking righthand side of destructured object
                        if (!assignmentKeyEqualsValue && parent.key === node) {
                            return;
                        }

                        const valueIsInvalid = parent.value.name && isInvalid(name);

                        // ignore destructuring if the option is set, unless a new identifier is created
                        if (valueIsInvalid && !(assignmentKeyEqualsValue && ignoreDestructuring)) {
                            report(node);
                        }
                    }

                    // never check properties or always ignore destructuring
                    if (!properties || (ignoreDestructuring && isInsideObjectPattern(node))) {
                        return;
                    }

                    // don't check right hand side of AssignmentExpression to prevent duplicate warnings
                    if (parent.right !== node && shouldReport(effectiveParent, name)) {
                        report(node);
                    }

                // Check if it's an import specifier
                } else if (IMPORT_TYPES.has(parent.type)) {

                    // Report only if the local imported identifier is invalid
                    if (parent.local && parent.local.name === node.name && isInvalid(name)) {
                        report(node);
                    }

                // Report anything that is invalid that isn't a CallExpression
                } else if (shouldReport(effectiveParent, name)) {
                    report(node);
                }
            }

        };

    }
};
