/**
 * @fileoverview This rule shoud require or disallow spaces before or after unary operations.
 * @author Marcin Kumorek
 */
"use strict";

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

const astUtils = require("../ast-utils");

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

module.exports = {
    meta: {
        docs: {
            description: "enforce consistent spacing before or after unary operators",
            category: "Stylistic Issues",
            recommended: false,
            url: "https://eslint.org/docs/rules/space-unary-ops"
        },

        fixable: "whitespace",

        schema: [
            {
                type: "object",
                properties: {
                    words: {
                        type: "boolean"
                    },
                    nonwords: {
                        type: "boolean"
                    },
                    overrides: {
                        type: "object",
                        additionalProperties: {
                            type: "boolean"
                        }
                    }
                },
                additionalProperties: false
            }
        ]
    },

    create(context) {
        const options = context.options && Array.isArray(context.options) && context.options[0] || { words: true, nonwords: false };

        const sourceCode = context.getSourceCode();

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

        /**
         * Check if the node is the first "!" in a "!!" convert to Boolean expression
         * @param {ASTnode} node AST node
         * @returns {boolean} Whether or not the node is first "!" in "!!"
         */
        function isFirstBangInBangBangExpression(node) {
            return node && node.type === "UnaryExpression" && node.argument.operator === "!" &&
                node.argument && node.argument.type === "UnaryExpression" && node.argument.operator === "!";
        }

        /**
         * Check if the node's child argument is an "ObjectExpression"
         * @param {ASTnode} node AST node
         * @returns {boolean} Whether or not the argument's type is "ObjectExpression"
         */
        function isArgumentObjectExpression(node) {
            return node.argument && node.argument.type && node.argument.type === "ObjectExpression";
        }

        /**
         * Checks if an override exists for a given operator.
         * @param {string} operator Operator
         * @returns {boolean} Whether or not an override has been provided for the operator
         */
        function overrideExistsForOperator(operator) {
            return options.overrides && options.overrides.hasOwnProperty(operator);
        }

        /**
         * Gets the value that the override was set to for this operator
         * @param {string} operator Operator
         * @returns {boolean} Whether or not an override enforces a space with this operator
         */
        function overrideEnforcesSpaces(operator) {
            return options.overrides[operator];
        }

        /**
         * Verify Unary Word Operator has spaces after the word operator
         * @param {ASTnode} node AST node
         * @param {Object} firstToken first token from the AST node
         * @param {Object} secondToken second token from the AST node
         * @param {string} word The word to be used for reporting
         * @returns {void}
         */
        function verifyWordHasSpaces(node, firstToken, secondToken, word) {
            if (secondToken.range[0] === firstToken.range[1]) {
                context.report({
                    node,
                    message: "Unary word operator '{{word}}' must be followed by whitespace.",
                    data: {
                        word
                    },
                    fix(fixer) {
                        return fixer.insertTextAfter(firstToken, " ");
                    }
                });
            }
        }

        /**
         * Verify Unary Word Operator doesn't have spaces after the word operator
         * @param {ASTnode} node AST node
         * @param {Object} firstToken first token from the AST node
         * @param {Object} secondToken second token from the AST node
         * @param {string} word The word to be used for reporting
         * @returns {void}
         */
        function verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word) {
            if (isArgumentObjectExpression(node)) {
                if (secondToken.range[0] > firstToken.range[1]) {
                    context.report({
                        node,
                        message: "Unexpected space after unary word operator '{{word}}'.",
                        data: {
                            word
                        },
                        fix(fixer) {
                            return fixer.removeRange([firstToken.range[1], secondToken.range[0]]);
                        }
                    });
                }
            }
        }

        /**
         * Check Unary Word Operators for spaces after the word operator
         * @param {ASTnode} node AST node
         * @param {Object} firstToken first token from the AST node
         * @param {Object} secondToken second token from the AST node
         * @param {string} word The word to be used for reporting
         * @returns {void}
         */
        function checkUnaryWordOperatorForSpaces(node, firstToken, secondToken, word) {
            word = word || firstToken.value;

            if (overrideExistsForOperator(word)) {
                if (overrideEnforcesSpaces(word)) {
                    verifyWordHasSpaces(node, firstToken, secondToken, word);
                } else {
                    verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word);
                }
            } else if (options.words) {
                verifyWordHasSpaces(node, firstToken, secondToken, word);
            } else {
                verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word);
            }
        }

        /**
         * Verifies YieldExpressions satisfy spacing requirements
         * @param {ASTnode} node AST node
         * @returns {void}
         */
        function checkForSpacesAfterYield(node) {
            const tokens = sourceCode.getFirstTokens(node, 3),
                word = "yield";

            if (!node.argument || node.delegate) {
                return;
            }

            checkUnaryWordOperatorForSpaces(node, tokens[0], tokens[1], word);
        }

        /**
         * Verifies AwaitExpressions satisfy spacing requirements
         * @param {ASTNode} node AwaitExpression AST node
         * @returns {void}
         */
        function checkForSpacesAfterAwait(node) {
            const tokens = sourceCode.getFirstTokens(node, 3);

            checkUnaryWordOperatorForSpaces(node, tokens[0], tokens[1], "await");
        }

        /**
         * Verifies UnaryExpression, UpdateExpression and NewExpression have spaces before or after the operator
         * @param {ASTnode} node AST node
         * @param {Object} firstToken First token in the expression
         * @param {Object} secondToken Second token in the expression
         * @returns {void}
         */
        function verifyNonWordsHaveSpaces(node, firstToken, secondToken) {
            if (node.prefix) {
                if (isFirstBangInBangBangExpression(node)) {
                    return;
                }
                if (firstToken.range[1] === secondToken.range[0]) {
                    context.report({
                        node,
                        message: "Unary operator '{{operator}}' must be followed by whitespace.",
                        data: {
                            operator: firstToken.value
                        },
                        fix(fixer) {
                            return fixer.insertTextAfter(firstToken, " ");
                        }
                    });
                }
            } else {
                if (firstToken.range[1] === secondToken.range[0]) {
                    context.report({
                        node,
                        message: "Space is required before unary expressions '{{token}}'.",
                        data: {
                            token: secondToken.value
                        },
                        fix(fixer) {
                            return fixer.insertTextBefore(secondToken, " ");
                        }
                    });
                }
            }
        }

        /**
         * Verifies UnaryExpression, UpdateExpression and NewExpression don't have spaces before or after the operator
         * @param {ASTnode} node AST node
         * @param {Object} firstToken First token in the expression
         * @param {Object} secondToken Second token in the expression
         * @returns {void}
         */
        function verifyNonWordsDontHaveSpaces(node, firstToken, secondToken) {
            if (node.prefix) {
                if (secondToken.range[0] > firstToken.range[1]) {
                    context.report({
                        node,
                        message: "Unexpected space after unary operator '{{operator}}'.",
                        data: {
                            operator: firstToken.value
                        },
                        fix(fixer) {
                            if (astUtils.canTokensBeAdjacent(firstToken, secondToken)) {
                                return fixer.removeRange([firstToken.range[1], secondToken.range[0]]);
                            }
                            return null;
                        }
                    });
                }
            } else {
                if (secondToken.range[0] > firstToken.range[1]) {
                    context.report({
                        node,
                        message: "Unexpected space before unary operator '{{operator}}'.",
                        data: {
                            operator: secondToken.value
                        },
                        fix(fixer) {
                            return fixer.removeRange([firstToken.range[1], secondToken.range[0]]);
                        }
                    });
                }
            }
        }

        /**
         * Verifies UnaryExpression, UpdateExpression and NewExpression satisfy spacing requirements
         * @param {ASTnode} node AST node
         * @returns {void}
         */
        function checkForSpaces(node) {
            const tokens = node.type === "UpdateExpression" && !node.prefix
                ? sourceCode.getLastTokens(node, 2)
                : sourceCode.getFirstTokens(node, 2);
            const firstToken = tokens[0];
            const secondToken = tokens[1];

            if ((node.type === "NewExpression" || node.prefix) && firstToken.type === "Keyword") {
                checkUnaryWordOperatorForSpaces(node, firstToken, secondToken);
                return;
            }

            const operator = node.prefix ? tokens[0].value : tokens[1].value;

            if (overrideExistsForOperator(operator)) {
                if (overrideEnforcesSpaces(operator)) {
                    verifyNonWordsHaveSpaces(node, firstToken, secondToken);
                } else {
                    verifyNonWordsDontHaveSpaces(node, firstToken, secondToken);
                }
            } else if (options.nonwords) {
                verifyNonWordsHaveSpaces(node, firstToken, secondToken);
            } else {
                verifyNonWordsDontHaveSpaces(node, firstToken, secondToken);
            }
        }

        //--------------------------------------------------------------------------
        // Public
        //--------------------------------------------------------------------------

        return {
            UnaryExpression: checkForSpaces,
            UpdateExpression: checkForSpaces,
            NewExpression: checkForSpaces,
            YieldExpression: checkForSpacesAfterYield,
            AwaitExpression: checkForSpacesAfterAwait
        };

    }
};
