/**
 * @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: {
        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
                    }
                ]
            }
        ]
    },

    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
            );
        }

        /**
         * 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 type = spaceRequired ? "Missing" : "Unexpected";
                const message = "{{type}} space {{side}} *.";
                const data = {
                    type,
                    side
                };

                context.report({
                    node,
                    message,
                    data,
                    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
        };

    }
};
