import { kindIcon } from '../domain/queries.js';
import { flowData, listEntryPointsData } from '../features/flow.js';
import { outputResult } from '../infrastructure/result-formatter.js';
function runListEntryPoints(dbPath, opts) {
    const data = listEntryPointsData(dbPath, {
        noTests: opts.noTests,
        limit: opts.limit,
        offset: opts.offset,
    });
    if (outputResult(data, 'entries', opts))
        return;
    if (data.count === 0) {
        console.log('No entry points found. Run "codegraph build" first.');
        return;
    }
    console.log(`\nEntry points (${data.count} total):\n`);
    for (const [type, entries] of Object.entries(data.byType)) {
        console.log(`  ${type} (${entries.length}):`);
        for (const e of entries) {
            console.log(`    [${kindIcon(e.kind)}] ${e.name}  ${e.file}:${e.line}`);
        }
        console.log();
    }
}
function printFlowHeader(data) {
    const e = data.entry;
    if (!e)
        return;
    const typeTag = e.type !== 'exported' ? ` (${e.type})` : '';
    console.log(`\nFlow from: [${kindIcon(e.kind)}] ${e.name}${typeTag}  ${e.file}:${e.line}`);
    console.log(`Depth: ${data.depth}  Reached: ${data.totalReached} nodes  Leaves: ${data.leaves.length}`);
    if (data.truncated) {
        console.log(`  (truncated at depth ${data.depth})`);
    }
    console.log();
}
function isLeafNode(n, leaves) {
    return leaves.some((l) => l.name === n.name && l.file === n.file);
}
/** Returns true when the node is a leaf (no steps); caller should skip cycle output. */
function printFlowSteps(data) {
    if (data.steps.length === 0) {
        console.log('  (leaf node — no callees)');
        return true;
    }
    for (const step of data.steps) {
        console.log(`  depth ${step.depth}:`);
        for (const n of step.nodes) {
            const leafTag = isLeafNode(n, data.leaves) ? ' [leaf]' : '';
            console.log(`    [${kindIcon(n.kind)}] ${n.name}  ${n.file}:${n.line}${leafTag}`);
        }
    }
    return false;
}
function printFlowCycles(cycles) {
    if (cycles.length === 0)
        return;
    console.log('\n  Cycles detected:');
    for (const c of cycles) {
        console.log(`    ${c.from} -> ${c.to} (at depth ${c.depth})`);
    }
}
export function flow(name, dbPath, opts = {}) {
    if (opts.list) {
        runListEntryPoints(dbPath, opts);
        return;
    }
    if (!name) {
        console.log('Please provide a function or entry-point name. Use --list to see available entry points.');
        return;
    }
    const data = flowData(name, dbPath, opts);
    if (outputResult(data, 'steps', opts))
        return;
    if (!data.entry) {
        console.log(`No matching entry point or function found for "${name}".`);
        return;
    }
    printFlowHeader(data);
    const isLeaf = printFlowSteps(data);
    if (!isLeaf) {
        printFlowCycles(data.cycles);
    }
}
//# sourceMappingURL=flow.js.map