/**
 * @fileoverview Rule to enforce grouped require statements for Node.JS
 * @author Raphael Pigulla
 */

"use strict";

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

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

        docs: {
            description: "disallow `require` calls to be mixed with regular variable declarations",
            category: "Node.js and CommonJS",
            recommended: false,
            url: "https://eslint.org/docs/rules/no-mixed-requires"
        },

        schema: [
            {
                oneOf: [
                    {
                        type: "boolean"
                    },
                    {
                        type: "object",
                        properties: {
                            grouping: {
                                type: "boolean"
                            },
                            allowCall: {
                                type: "boolean"
                            }
                        },
                        additionalProperties: false
                    }
                ]
            }
        ]
    },

    create(context) {

        const options = context.options[0];
        let grouping = false,
            allowCall = false;

        if (typeof options === "object") {
            grouping = options.grouping;
            allowCall = options.allowCall;
        } else {
            grouping = !!options;
        }

        /**
         * Returns the list of built-in modules.
         *
         * @returns {string[]} An array of built-in Node.js modules.
         */
        function getBuiltinModules() {

            /*
             * This list is generated using:
             * `require("repl")._builtinLibs.concat('repl').sort()`
             * This particular list is as per nodejs v0.12.2 and iojs v0.7.1
             */
            return [
                "assert", "buffer", "child_process", "cluster", "crypto",
                "dgram", "dns", "domain", "events", "fs", "http", "https",
                "net", "os", "path", "punycode", "querystring", "readline",
                "repl", "smalloc", "stream", "string_decoder", "tls", "tty",
                "url", "util", "v8", "vm", "zlib"
            ];
        }

        const BUILTIN_MODULES = getBuiltinModules();

        const DECL_REQUIRE = "require",
            DECL_UNINITIALIZED = "uninitialized",
            DECL_OTHER = "other";

        const REQ_CORE = "core",
            REQ_FILE = "file",
            REQ_MODULE = "module",
            REQ_COMPUTED = "computed";

        /**
         * Determines the type of a declaration statement.
         * @param {ASTNode} initExpression The init node of the VariableDeclarator.
         * @returns {string} The type of declaration represented by the expression.
         */
        function getDeclarationType(initExpression) {
            if (!initExpression) {

                // "var x;"
                return DECL_UNINITIALIZED;
            }

            if (initExpression.type === "CallExpression" &&
                initExpression.callee.type === "Identifier" &&
                initExpression.callee.name === "require"
            ) {

                // "var x = require('util');"
                return DECL_REQUIRE;
            }
            if (allowCall &&
                initExpression.type === "CallExpression" &&
                initExpression.callee.type === "CallExpression"
            ) {

                // "var x = require('diagnose')('sub-module');"
                return getDeclarationType(initExpression.callee);
            }
            if (initExpression.type === "MemberExpression") {

                // "var x = require('glob').Glob;"
                return getDeclarationType(initExpression.object);
            }

            // "var x = 42;"
            return DECL_OTHER;
        }

        /**
         * Determines the type of module that is loaded via require.
         * @param {ASTNode} initExpression The init node of the VariableDeclarator.
         * @returns {string} The module type.
         */
        function inferModuleType(initExpression) {
            if (initExpression.type === "MemberExpression") {

                // "var x = require('glob').Glob;"
                return inferModuleType(initExpression.object);
            }
            if (initExpression.arguments.length === 0) {

                // "var x = require();"
                return REQ_COMPUTED;
            }

            const arg = initExpression.arguments[0];

            if (arg.type !== "Literal" || typeof arg.value !== "string") {

                // "var x = require(42);"
                return REQ_COMPUTED;
            }

            if (BUILTIN_MODULES.indexOf(arg.value) !== -1) {

                // "var fs = require('fs');"
                return REQ_CORE;
            }
            if (/^\.{0,2}\//u.test(arg.value)) {

                // "var utils = require('./utils');"
                return REQ_FILE;
            }

            // "var async = require('async');"
            return REQ_MODULE;

        }

        /**
         * Check if the list of variable declarations is mixed, i.e. whether it
         * contains both require and other declarations.
         * @param {ASTNode} declarations The list of VariableDeclarators.
         * @returns {boolean} True if the declarations are mixed, false if not.
         */
        function isMixed(declarations) {
            const contains = {};

            declarations.forEach(declaration => {
                const type = getDeclarationType(declaration.init);

                contains[type] = true;
            });

            return !!(
                contains[DECL_REQUIRE] &&
                (contains[DECL_UNINITIALIZED] || contains[DECL_OTHER])
            );
        }

        /**
         * Check if all require declarations in the given list are of the same
         * type.
         * @param {ASTNode} declarations The list of VariableDeclarators.
         * @returns {boolean} True if the declarations are grouped, false if not.
         */
        function isGrouped(declarations) {
            const found = {};

            declarations.forEach(declaration => {
                if (getDeclarationType(declaration.init) === DECL_REQUIRE) {
                    found[inferModuleType(declaration.init)] = true;
                }
            });

            return Object.keys(found).length <= 1;
        }


        return {

            VariableDeclaration(node) {

                if (isMixed(node.declarations)) {
                    context.report({ node, message: "Do not mix 'require' and other declarations." });
                } else if (grouping && !isGrouped(node.declarations)) {
                    context.report({ node, message: "Do not mix core, module, file and computed requires." });
                }
            }
        };

    }
};
