/**
 * @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.
 */
/* c8 ignore next */
// eslint-disable-next-line jsdoc/require-jsdoc -- Ignoring
function getId(segment) {
	return segment.id + (segment.reachable ? "" : "!");
}

/**
 * Get string for the given node and operation.
 * @param {ASTNode} node The node to convert.
 * @param {"enter" | "exit" | undefined} label The operation label.
 * @returns {string} The string representation.
 */
function nodeToString(node, label) {
	const suffix = label ? `:${label}` : "";

	switch (node.type) {
		case "Identifier":
			return `${node.type}${suffix} (${node.name})`;
		case "Literal":
			return `${node.type}${suffix} (${node.value})`;
		default:
			return `${node.type}${suffix}`;
	}
}

//------------------------------------------------------------------------------
// 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
		: /* c8 ignore next */ function (node, state, leaving) {
				for (let i = 0; i < state.currentSegments.length; ++i) {
					const segInternal = state.currentSegments[i].internal;

					if (leaving) {
						const last = segInternal.nodes.length - 1;

						if (
							last >= 0 &&
							segInternal.nodes[last] ===
								nodeToString(node, "enter")
						) {
							segInternal.nodes[last] = nodeToString(
								node,
								void 0,
							);
						} else {
							segInternal.nodes.push(nodeToString(node, "exit"));
						}
					} else {
						segInternal.nodes.push(nodeToString(node, "enter"));
					}
				}

				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 visualized 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
		: /* c8 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=true];\n';
				}

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

				// eslint-disable-next-line guard-for-in -- Want ability to traverse prototype
				for (const id in traceMap) {
					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) {
						text += segment.internal.nodes.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 visualized 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};`;
	},
};
