/**
 * @fileoverview Helpers to debug for code path analysis.
 * @author Toru Nagashima
 */

"use strict";

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

const debug = require("debug")("eslint:code-path");

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

/**
 * Gets id of a given segment.
 * @param {CodePathSegment} segment - A segment to get.
 * @returns {string} Id of the segment.
 */
/* istanbul ignore next */
function getId(segment) { // eslint-disable-line require-jsdoc
    return segment.id + (segment.reachable ? "" : "!");
}

//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------

module.exports = {

    /**
     * A flag that debug dumping is enabled or not.
     * @type {boolean}
     */
    enabled: debug.enabled,

    /**
     * Dumps given objects.
     *
     * @param {...any} args - objects to dump.
     * @returns {void}
     */
    dump: debug,

    /**
     * Dumps the current analyzing state.
     *
     * @param {ASTNode} node - A node to dump.
     * @param {CodePathState} state - A state to dump.
     * @param {boolean} leaving - A flag whether or not it's leaving
     * @returns {void}
     */
    dumpState: !debug.enabled ? debug : /* istanbul ignore next */ function(node, state, leaving) {
        for (let i = 0; i < state.currentSegments.length; ++i) {
            const segInternal = state.currentSegments[i].internal;

            if (leaving) {
                segInternal.exitNodes.push(node);
            } else {
                segInternal.nodes.push(node);
            }
        }

        debug([
            `${state.currentSegments.map(getId).join(",")})`,
            `${node.type}${leaving ? ":exit" : ""}`
        ].join(" "));
    },

    /**
     * Dumps a DOT code of a given code path.
     * The DOT code can be visialized with Graphvis.
     *
     * @param {CodePath} codePath - A code path to dump.
     * @returns {void}
     * @see http://www.graphviz.org
     * @see http://www.webgraphviz.com
     */
    dumpDot: !debug.enabled ? debug : /* istanbul ignore next */ function(codePath) {
        let text =
            "\n" +
            "digraph {\n" +
            "node[shape=box,style=\"rounded,filled\",fillcolor=white];\n" +
            "initial[label=\"\",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];\n";

        if (codePath.returnedSegments.length > 0) {
            text += "final[label=\"\",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];\n";
        }
        if (codePath.thrownSegments.length > 0) {
            text += "thrown[label=\"✘\",shape=circle,width=0.3,height=0.3,fixedsize];\n";
        }

        const traceMap = Object.create(null);
        const arrows = this.makeDotArrows(codePath, traceMap);

        for (const id in traceMap) { // eslint-disable-line guard-for-in
            const segment = traceMap[id];

            text += `${id}[`;

            if (segment.reachable) {
                text += "label=\"";
            } else {
                text += "style=\"rounded,dashed,filled\",fillcolor=\"#FF9800\",label=\"<<unreachable>>\\n";
            }

            if (segment.internal.nodes.length > 0 || segment.internal.exitNodes.length > 0) {
                text += [].concat(
                    segment.internal.nodes.map(node => {
                        switch (node.type) {
                            case "Identifier": return `${node.type} (${node.name})`;
                            case "Literal": return `${node.type} (${node.value})`;
                            default: return node.type;
                        }
                    }),
                    segment.internal.exitNodes.map(node => {
                        switch (node.type) {
                            case "Identifier": return `${node.type}:exit (${node.name})`;
                            case "Literal": return `${node.type}:exit (${node.value})`;
                            default: return `${node.type}:exit`;
                        }
                    })
                ).join("\\n");
            } else {
                text += "????";
            }

            text += "\"];\n";
        }

        text += `${arrows}\n`;
        text += "}";
        debug("DOT", text);
    },

    /**
     * Makes a DOT code of a given code path.
     * The DOT code can be visialized with Graphvis.
     *
     * @param {CodePath} codePath - A code path to make DOT.
     * @param {Object} traceMap - Optional. A map to check whether or not segments had been done.
     * @returns {string} A DOT code of the code path.
     */
    makeDotArrows(codePath, traceMap) {
        const stack = [[codePath.initialSegment, 0]];
        const done = traceMap || Object.create(null);
        let lastId = codePath.initialSegment.id;
        let text = `initial->${codePath.initialSegment.id}`;

        while (stack.length > 0) {
            const item = stack.pop();
            const segment = item[0];
            const index = item[1];

            if (done[segment.id] && index === 0) {
                continue;
            }
            done[segment.id] = segment;

            const nextSegment = segment.allNextSegments[index];

            if (!nextSegment) {
                continue;
            }

            if (lastId === segment.id) {
                text += `->${nextSegment.id}`;
            } else {
                text += `;\n${segment.id}->${nextSegment.id}`;
            }
            lastId = nextSegment.id;

            stack.unshift([segment, 1 + index]);
            stack.push([nextSegment, 0]);
        }

        codePath.returnedSegments.forEach(finalSegment => {
            if (lastId === finalSegment.id) {
                text += "->final";
            } else {
                text += `;\n${finalSegment.id}->final`;
            }
            lastId = null;
        });

        codePath.thrownSegments.forEach(finalSegment => {
            if (lastId === finalSegment.id) {
                text += "->thrown";
            } else {
                text += `;\n${finalSegment.id}->thrown`;
            }
            lastId = null;
        });

        return `${text};`;
    }
};
