/**
 * @fileoverview Rule to check the spacing around the * in generator functions.
 * @author Jamund Ferguson
 */

"use strict";

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

const OVERRIDE_SCHEMA = {
    oneOf: [
        {
            enum: ["before", "after", "both", "neither"]
        },
        {
            type: "object",
            properties: {
                before: { type: "boolean" },
                after: { type: "boolean" }
            },
            additionalProperties: false
        }
    ]
};

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

        docs: {
            description: "enforce consistent spacing around `*` operators in generator functions",
            category: "ECMAScript 6",
            recommended: false,
            url: "https://eslint.org/docs/rules/generator-star-spacing"
        },

        fixable: "whitespace",

        schema: [
            {
                oneOf: [
                    {
                        enum: ["before", "after", "both", "neither"]
                    },
                    {
                        type: "object",
                        properties: {
                            before: { type: "boolean" },
                            after: { type: "boolean" },
                            named: OVERRIDE_SCHEMA,
                            anonymous: OVERRIDE_SCHEMA,
                            method: OVERRIDE_SCHEMA
                        },
                        additionalProperties: false
                    }
                ]
            }
        ],

        messages: {
            missingBefore: "Missing space before *.",
            missingAfter: "Missing space after *.",
            unexpectedBefore: "Unexpected space before *.",
            unexpectedAfter: "Unexpected space after *."
        }
    },

    create(context) {

        const optionDefinitions = {
            before: { before: true, after: false },
            after: { before: false, after: true },
            both: { before: true, after: true },
            neither: { before: false, after: false }
        };

        /**
         * Returns resolved option definitions based on an option and defaults
         *
         * @param {any} option - The option object or string value
         * @param {Object} defaults - The defaults to use if options are not present
         * @returns {Object} the resolved object definition
         */
        function optionToDefinition(option, defaults) {
            if (!option) {
                return defaults;
            }

            return typeof option === "string"
                ? optionDefinitions[option]
                : Object.assign({}, defaults, option);
        }

        const modes = (function(option) {
            const defaults = optionToDefinition(option, optionDefinitions.before);

            return {
                named: optionToDefinition(option.named, defaults),
                anonymous: optionToDefinition(option.anonymous, defaults),
                method: optionToDefinition(option.method, defaults)
            };
        }(context.options[0] || {}));

        const sourceCode = context.getSourceCode();

        /**
         * Checks if the given token is a star token or not.
         *
         * @param {Token} token - The token to check.
         * @returns {boolean} `true` if the token is a star token.
         */
        function isStarToken(token) {
            return token.value === "*" && token.type === "Punctuator";
        }

        /**
         * Gets the generator star token of the given function node.
         *
         * @param {ASTNode} node - The function node to get.
         * @returns {Token} Found star token.
         */
        function getStarToken(node) {
            return sourceCode.getFirstToken(
                (node.parent.method || node.parent.type === "MethodDefinition") ? node.parent : node,
                isStarToken
            );
        }

        /**
         * capitalize a given string.
         * @param {string} str the given string.
         * @returns {string} the capitalized string.
         */
        function capitalize(str) {
            return str[0].toUpperCase() + str.slice(1);
        }

        /**
         * Checks the spacing between two tokens before or after the star token.
         *
         * @param {string} kind Either "named", "anonymous", or "method"
         * @param {string} side Either "before" or "after".
         * @param {Token} leftToken `function` keyword token if side is "before", or
         *     star token if side is "after".
         * @param {Token} rightToken Star token if side is "before", or identifier
         *     token if side is "after".
         * @returns {void}
         */
        function checkSpacing(kind, side, leftToken, rightToken) {
            if (!!(rightToken.range[0] - leftToken.range[1]) !== modes[kind][side]) {
                const after = leftToken.value === "*";
                const spaceRequired = modes[kind][side];
                const node = after ? leftToken : rightToken;
                const messageId = `${spaceRequired ? "missing" : "unexpected"}${capitalize(side)}`;

                context.report({
                    node,
                    messageId,
                    fix(fixer) {
                        if (spaceRequired) {
                            if (after) {
                                return fixer.insertTextAfter(node, " ");
                            }
                            return fixer.insertTextBefore(node, " ");
                        }
                        return fixer.removeRange([leftToken.range[1], rightToken.range[0]]);
                    }
                });
            }
        }

        /**
         * Enforces the spacing around the star if node is a generator function.
         *
         * @param {ASTNode} node A function expression or declaration node.
         * @returns {void}
         */
        function checkFunction(node) {
            if (!node.generator) {
                return;
            }

            const starToken = getStarToken(node);
            const prevToken = sourceCode.getTokenBefore(starToken);
            const nextToken = sourceCode.getTokenAfter(starToken);

            let kind = "named";

            if (node.parent.type === "MethodDefinition" || (node.parent.type === "Property" && node.parent.method)) {
                kind = "method";
            } else if (!node.id) {
                kind = "anonymous";
            }

            // Only check before when preceded by `function`|`static` keyword
            if (!(kind === "method" && starToken === sourceCode.getFirstToken(node.parent))) {
                checkSpacing(kind, "before", prevToken, starToken);
            }

            checkSpacing(kind, "after", starToken, nextToken);
        }

        return {
            FunctionDeclaration: checkFunction,
            FunctionExpression: checkFunction
        };

    }
};
