/**
 * @fileoverview Enforces that a return statement is present in property getters.
 * @author Aladdin-ADD(hh_2013@foxmail.com)
 */

"use strict";

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

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

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u;

/**
 * Checks a given code path segment is reachable.
 *
 * @param {CodePathSegment} segment - A segment to check.
 * @returns {boolean} `true` if the segment is reachable.
 */
function isReachable(segment) {
    return segment.reachable;
}

/**
 * Gets a readable location.
 *
 * - FunctionExpression -> the function name or `function` keyword.
 *
 * @param {ASTNode} node - A function node to get.
 * @returns {ASTNode|Token} The node or the token of a location.
 */
function getId(node) {
    return node.id || node;
}

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

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

        docs: {
            description: "enforce `return` statements in getters",
            category: "Possible Errors",
            recommended: true,
            url: "https://eslint.org/docs/rules/getter-return"
        },

        fixable: null,

        schema: [
            {
                type: "object",
                properties: {
                    allowImplicit: {
                        type: "boolean",
                        default: false
                    }
                },
                additionalProperties: false
            }
        ],

        messages: {
            expected: "Expected to return a value in {{name}}.",
            expectedAlways: "Expected {{name}} to always return a value."
        }
    },

    create(context) {

        const options = context.options[0] || { allowImplicit: false };

        let funcInfo = {
            upper: null,
            codePath: null,
            hasReturn: false,
            shouldCheck: false,
            node: null
        };

        /**
         * Checks whether or not the last code path segment is reachable.
         * Then reports this function if the segment is reachable.
         *
         * If the last code path segment is reachable, there are paths which are not
         * returned or thrown.
         *
         * @param {ASTNode} node - A node to check.
         * @returns {void}
         */
        function checkLastSegment(node) {
            if (funcInfo.shouldCheck &&
                funcInfo.codePath.currentSegments.some(isReachable)
            ) {
                context.report({
                    node,
                    loc: getId(node).loc.start,
                    messageId: funcInfo.hasReturn ? "expectedAlways" : "expected",
                    data: {
                        name: astUtils.getFunctionNameWithKind(funcInfo.node)
                    }
                });
            }
        }

        /**
         * Checks whether a node means a getter function.
         * @param {ASTNode} node - a node to check.
         * @returns {boolean} if node means a getter, return true; else return false.
         */
        function isGetter(node) {
            const parent = node.parent;

            if (TARGET_NODE_TYPE.test(node.type) && node.body.type === "BlockStatement") {
                if (parent.kind === "get") {
                    return true;
                }
                if (parent.type === "Property" && astUtils.getStaticPropertyName(parent) === "get" && parent.parent.type === "ObjectExpression") {

                    // Object.defineProperty()
                    if (parent.parent.parent.type === "CallExpression" &&
                        astUtils.getStaticPropertyName(parent.parent.parent.callee) === "defineProperty") {
                        return true;
                    }

                    // Object.defineProperties()
                    if (parent.parent.parent.type === "Property" &&
                        parent.parent.parent.parent.type === "ObjectExpression" &&
                        parent.parent.parent.parent.parent.type === "CallExpression" &&
                        astUtils.getStaticPropertyName(parent.parent.parent.parent.parent.callee) === "defineProperties") {
                        return true;
                    }
                }
            }
            return false;
        }
        return {

            // Stacks this function's information.
            onCodePathStart(codePath, node) {
                funcInfo = {
                    upper: funcInfo,
                    codePath,
                    hasReturn: false,
                    shouldCheck: isGetter(node),
                    node
                };
            },

            // Pops this function's information.
            onCodePathEnd() {
                funcInfo = funcInfo.upper;
            },

            // Checks the return statement is valid.
            ReturnStatement(node) {
                if (funcInfo.shouldCheck) {
                    funcInfo.hasReturn = true;

                    // if allowImplicit: false, should also check node.argument
                    if (!options.allowImplicit && !node.argument) {
                        context.report({
                            node,
                            messageId: "expected",
                            data: {
                                name: astUtils.getFunctionNameWithKind(funcInfo.node)
                            }
                        });
                    }
                }
            },

            // Reports a given function if the last path is reachable.
            "FunctionExpression:exit": checkLastSegment,
            "ArrowFunctionExpression:exit": checkLastSegment
        };
    }
};
