/**
 * @fileoverview Rule to require parens in arrow function arguments.
 * @author Jxck
 */
"use strict";

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

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

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

/**
 * Get location should be reported by AST node.
 *
 * @param {ASTNode} node AST Node.
 * @returns {Location} Location information.
 */
function getLocation(node) {
    return {
        start: node.params[0].loc.start,
        end: node.params[node.params.length - 1].loc.end
    };
}

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

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

        docs: {
            description: "require parentheses around arrow function arguments",
            category: "ECMAScript 6",
            recommended: false,
            url: "https://eslint.org/docs/rules/arrow-parens"
        },

        fixable: "code",

        schema: [
            {
                enum: ["always", "as-needed"]
            },
            {
                type: "object",
                properties: {
                    requireForBlockBody: {
                        type: "boolean",
                        default: false
                    }
                },
                additionalProperties: false
            }
        ],

        messages: {
            unexpectedParens: "Unexpected parentheses around single function argument.",
            expectedParens: "Expected parentheses around arrow function argument.",

            unexpectedParensInline: "Unexpected parentheses around single function argument having a body with no curly braces.",
            expectedParensBlock: "Expected parentheses around arrow function argument having a body with curly braces."
        }
    },

    create(context) {
        const asNeeded = context.options[0] === "as-needed";
        const requireForBlockBody = asNeeded && context.options[1] && context.options[1].requireForBlockBody === true;

        const sourceCode = context.getSourceCode();

        /**
         * Determines whether a arrow function argument end with `)`
         * @param {ASTNode} node The arrow function node.
         * @returns {void}
         */
        function parens(node) {
            const isAsync = node.async;
            const firstTokenOfParam = sourceCode.getFirstToken(node, isAsync ? 1 : 0);

            /**
             * Remove the parenthesis around a parameter
             * @param {Fixer} fixer Fixer
             * @returns {string} fixed parameter
             */
            function fixParamsWithParenthesis(fixer) {
                const paramToken = sourceCode.getTokenAfter(firstTokenOfParam);

                /*
                 * ES8 allows Trailing commas in function parameter lists and calls
                 * https://github.com/eslint/eslint/issues/8834
                 */
                const closingParenToken = sourceCode.getTokenAfter(paramToken, astUtils.isClosingParenToken);
                const asyncToken = isAsync ? sourceCode.getTokenBefore(firstTokenOfParam) : null;
                const shouldAddSpaceForAsync = asyncToken && (asyncToken.range[1] === firstTokenOfParam.range[0]);

                return fixer.replaceTextRange([
                    firstTokenOfParam.range[0],
                    closingParenToken.range[1]
                ], `${shouldAddSpaceForAsync ? " " : ""}${paramToken.value}`);
            }

            // "as-needed", { "requireForBlockBody": true }: x => x
            if (
                requireForBlockBody &&
                node.params.length === 1 &&
                node.params[0].type === "Identifier" &&
                !node.params[0].typeAnnotation &&
                node.body.type !== "BlockStatement" &&
                !node.returnType
            ) {
                if (astUtils.isOpeningParenToken(firstTokenOfParam)) {
                    context.report({
                        node,
                        messageId: "unexpectedParensInline",
                        loc: getLocation(node),
                        fix: fixParamsWithParenthesis
                    });
                }
                return;
            }

            if (
                requireForBlockBody &&
                node.body.type === "BlockStatement"
            ) {
                if (!astUtils.isOpeningParenToken(firstTokenOfParam)) {
                    context.report({
                        node,
                        messageId: "expectedParensBlock",
                        loc: getLocation(node),
                        fix(fixer) {
                            return fixer.replaceText(firstTokenOfParam, `(${firstTokenOfParam.value})`);
                        }
                    });
                }
                return;
            }

            // "as-needed": x => x
            if (asNeeded &&
                node.params.length === 1 &&
                node.params[0].type === "Identifier" &&
                !node.params[0].typeAnnotation &&
                !node.returnType
            ) {
                if (astUtils.isOpeningParenToken(firstTokenOfParam)) {
                    context.report({
                        node,
                        messageId: "unexpectedParens",
                        loc: getLocation(node),
                        fix: fixParamsWithParenthesis
                    });
                }
                return;
            }

            if (firstTokenOfParam.type === "Identifier") {
                const after = sourceCode.getTokenAfter(firstTokenOfParam);

                // (x) => x
                if (after.value !== ")") {
                    context.report({
                        node,
                        messageId: "expectedParens",
                        loc: getLocation(node),
                        fix(fixer) {
                            return fixer.replaceText(firstTokenOfParam, `(${firstTokenOfParam.value})`);
                        }
                    });
                }
            }
        }

        return {
            ArrowFunctionExpression: parens
        };
    }
};
