import { parser } from '../parser.js';
import { buildDiagramGraph } from './geometry.js';
import { renderSVG } from './renderer.js';
import { wrapSVGInHTML } from './html-viewer.js';
/**
 * Render a workflow AST to an SVG string.
 */
export function workflowToSVG(ast, options = {}) {
    const graph = buildDiagramGraph(ast, options);
    return renderSVG(graph, options);
}
/**
 * Parse TypeScript source code and render the first (or named) workflow to SVG.
 */
export function sourceToSVG(code, options = {}) {
    const result = parser.parseFromString(code);
    return pickAndRender(result.workflows, options);
}
/**
 * Parse a workflow file (resolves imports) and render the first (or named) workflow to SVG.
 */
export function fileToSVG(filePath, options = {}) {
    const result = parser.parse(filePath);
    return pickAndRender(result.workflows, options);
}
/**
 * Render a workflow AST to a self-contained interactive HTML page.
 */
export function workflowToHTML(ast, options = {}) {
    const svg = workflowToSVG(ast, options);
    return wrapSVGInHTML(svg, { title: options.workflowName ?? ast.name, theme: options.theme, nodeSources: buildNodeSourceMap(ast) });
}
/**
 * Parse TypeScript source code and render the first (or named) workflow to interactive HTML.
 */
export function sourceToHTML(code, options = {}) {
    const result = parser.parseFromString(code);
    const ast = pickWorkflow(result.workflows, options);
    const svg = workflowToSVG(ast, options);
    return wrapSVGInHTML(svg, { title: options.workflowName ?? ast.name, theme: options.theme, nodeSources: buildNodeSourceMap(ast) });
}
/**
 * Parse a workflow file and render the first (or named) workflow to interactive HTML.
 */
export function fileToHTML(filePath, options = {}) {
    const result = parser.parse(filePath);
    const ast = pickWorkflow(result.workflows, options);
    const svg = workflowToSVG(ast, options);
    return wrapSVGInHTML(svg, { title: options.workflowName ?? ast.name, theme: options.theme, nodeSources: buildNodeSourceMap(ast) });
}
function buildNodeSourceMap(ast) {
    const typeMap = new Map(ast.nodeTypes.map(nt => [nt.functionName, nt]));
    const map = {};
    for (const inst of ast.instances) {
        const nt = typeMap.get(inst.nodeType);
        if (!nt)
            continue;
        const ports = {};
        for (const [name, def] of Object.entries(nt.inputs ?? {})) {
            ports[name] = { type: def.dataType, tsType: def.tsType };
        }
        for (const [name, def] of Object.entries(nt.outputs ?? {})) {
            ports[name] = { type: def.dataType, tsType: def.tsType };
        }
        map[inst.id] = { description: nt.description, source: nt.functionText, ports };
    }
    // Virtual Start/Exit nodes get their port types from the workflow definition
    const startPorts = {};
    for (const [name, def] of Object.entries(ast.startPorts ?? {})) {
        startPorts[name] = { type: def.dataType, tsType: def.tsType };
    }
    if (Object.keys(startPorts).length) {
        map['Start'] = { description: ast.description, ports: startPorts };
    }
    const exitPorts = {};
    for (const [name, def] of Object.entries(ast.exitPorts ?? {})) {
        exitPorts[name] = { type: def.dataType, tsType: def.tsType };
    }
    if (Object.keys(exitPorts).length) {
        map['Exit'] = { ports: exitPorts };
    }
    return map;
}
function pickWorkflow(workflows, options) {
    if (workflows.length === 0) {
        throw new Error('No workflows found in source code');
    }
    if (options.workflowName) {
        const found = workflows.find(w => w.name === options.workflowName);
        if (!found) {
            throw new Error(`Workflow "${options.workflowName}" not found. Available: ${workflows.map(w => w.name).join(', ')}`);
        }
        return found;
    }
    return workflows[0];
}
function pickAndRender(workflows, options) {
    return workflowToSVG(pickWorkflow(workflows, options), options);
}
//# sourceMappingURL=index.js.map