/**
 * @fileoverview Enforce return after a callback.
 * @author Jamund Ferguson
 */
"use strict";

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

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

        docs: {
            description: "require `return` statements after callbacks",
            category: "Node.js and CommonJS",
            recommended: false,
            url: "https://eslint.org/docs/rules/callback-return"
        },

        schema: [{
            type: "array",
            items: { type: "string" }
        }],

        messages: {
            missingReturn: "Expected return with your callback function."
        }
    },

    create(context) {

        const callbacks = context.options[0] || ["callback", "cb", "next"],
            sourceCode = context.getSourceCode();

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

        /**
         * Find the closest parent matching a list of types.
         * @param {ASTNode} node The node whose parents we are searching
         * @param {Array} types The node types to match
         * @returns {ASTNode} The matched node or undefined.
         */
        function findClosestParentOfType(node, types) {
            if (!node.parent) {
                return null;
            }
            if (types.indexOf(node.parent.type) === -1) {
                return findClosestParentOfType(node.parent, types);
            }
            return node.parent;
        }

        /**
         * Check to see if a node contains only identifers
         * @param {ASTNode} node The node to check
         * @returns {boolean} Whether or not the node contains only identifers
         */
        function containsOnlyIdentifiers(node) {
            if (node.type === "Identifier") {
                return true;
            }

            if (node.type === "MemberExpression") {
                if (node.object.type === "Identifier") {
                    return true;
                }
                if (node.object.type === "MemberExpression") {
                    return containsOnlyIdentifiers(node.object);
                }
            }

            return false;
        }

        /**
         * Check to see if a CallExpression is in our callback list.
         * @param {ASTNode} node The node to check against our callback names list.
         * @returns {boolean} Whether or not this function matches our callback name.
         */
        function isCallback(node) {
            return containsOnlyIdentifiers(node.callee) && callbacks.indexOf(sourceCode.getText(node.callee)) > -1;
        }

        /**
         * Determines whether or not the callback is part of a callback expression.
         * @param {ASTNode} node The callback node
         * @param {ASTNode} parentNode The expression node
         * @returns {boolean} Whether or not this is part of a callback expression
         */
        function isCallbackExpression(node, parentNode) {

            // ensure the parent node exists and is an expression
            if (!parentNode || parentNode.type !== "ExpressionStatement") {
                return false;
            }

            // cb()
            if (parentNode.expression === node) {
                return true;
            }

            // special case for cb && cb() and similar
            if (parentNode.expression.type === "BinaryExpression" || parentNode.expression.type === "LogicalExpression") {
                if (parentNode.expression.right === node) {
                    return true;
                }
            }

            return false;
        }

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

        return {
            CallExpression(node) {

                // if we're not a callback we can return
                if (!isCallback(node)) {
                    return;
                }

                // find the closest block, return or loop
                const closestBlock = findClosestParentOfType(node, ["BlockStatement", "ReturnStatement", "ArrowFunctionExpression"]) || {};

                // if our parent is a return we know we're ok
                if (closestBlock.type === "ReturnStatement") {
                    return;
                }

                // arrow functions don't always have blocks and implicitly return
                if (closestBlock.type === "ArrowFunctionExpression") {
                    return;
                }

                // block statements are part of functions and most if statements
                if (closestBlock.type === "BlockStatement") {

                    // find the last item in the block
                    const lastItem = closestBlock.body[closestBlock.body.length - 1];

                    // if the callback is the last thing in a block that might be ok
                    if (isCallbackExpression(node, lastItem)) {

                        const parentType = closestBlock.parent.type;

                        // but only if the block is part of a function
                        if (parentType === "FunctionExpression" ||
                            parentType === "FunctionDeclaration" ||
                            parentType === "ArrowFunctionExpression"
                        ) {
                            return;
                        }

                    }

                    // ending a block with a return is also ok
                    if (lastItem.type === "ReturnStatement") {

                        // but only if the callback is immediately before
                        if (isCallbackExpression(node, closestBlock.body[closestBlock.body.length - 2])) {
                            return;
                        }
                    }

                }

                // as long as you're the child of a function at this point you should be asked to return
                if (findClosestParentOfType(node, ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"])) {
                    context.report({ node, messageId: "missingReturn" });
                }

            }

        };
    }
};
