import { childrenData, contextData, explainData, implementationsData, interfacesData, kindIcon, queryNameData, whereData, } from '../../domain/queries.js';
import { outputResult } from '../../infrastructure/result-formatter.js';
function renderWhereSymbolResults(results) {
    for (const r of results) {
        const roleTag = r.role ? ` [${r.role}]` : '';
        const tag = r.exported ? '  (exported)' : '';
        console.log(`\n${kindIcon(r.kind)} ${r.name}${roleTag}  ${r.file}:${r.line}${tag}`);
        if (r.uses.length > 0) {
            const useStrs = r.uses.map((u) => `${u.file}:${u.line}`);
            console.log(`  Used in: ${useStrs.join(', ')}`);
        }
        else {
            console.log('  No uses found');
        }
    }
}
function renderWhereFileResults(results) {
    for (const r of results) {
        console.log(`\n# ${r.file}`);
        if (r.symbols.length > 0) {
            const symStrs = r.symbols.map((s) => `${s.name}:${s.line}`);
            console.log(`  Symbols: ${symStrs.join(', ')}`);
        }
        if (r.imports.length > 0) {
            console.log(`  Imports: ${r.imports.join(', ')}`);
        }
        if (r.importedBy.length > 0) {
            console.log(`  Imported by: ${r.importedBy.join(', ')}`);
        }
        if (r.exported.length > 0) {
            console.log(`  Exported: ${r.exported.join(', ')}`);
        }
    }
}
export function where(target, customDbPath, opts = {}) {
    const data = whereData(target, customDbPath, opts);
    if (outputResult(data, 'results', opts))
        return;
    if (data.results.length === 0) {
        console.log(data.mode === 'file'
            ? `No file matching "${target}" in graph`
            : `No symbol matching "${target}" in graph`);
        return;
    }
    if (data.mode === 'symbol') {
        renderWhereSymbolResults(data.results);
    }
    else {
        renderWhereFileResults(data.results);
    }
    console.log();
}
export function queryName(name, customDbPath, opts = {}) {
    const data = queryNameData(name, customDbPath, {
        noTests: opts.noTests,
        limit: opts.limit,
        offset: opts.offset,
    });
    if (outputResult(data, 'results', opts))
        return;
    if (data.results.length === 0) {
        console.log(`No results for "${name}"`);
        return;
    }
    console.log(`\nResults for "${name}":\n`);
    for (const r of data.results) {
        console.log(`  ${kindIcon(r.kind)} ${r.name} (${r.kind}) -- ${r.file}:${r.line}`);
        if (r.callees.length > 0) {
            console.log(`    -> calls/uses:`);
            for (const c of r.callees.slice(0, 15))
                console.log(`      -> ${c.name} (${c.edgeKind}) ${c.file}:${c.line}`);
            if (r.callees.length > 15)
                console.log(`      ... and ${r.callees.length - 15} more`);
        }
        if (r.callers.length > 0) {
            console.log(`    <- called by:`);
            for (const c of r.callers.slice(0, 15))
                console.log(`      <- ${c.name} (${c.edgeKind}) ${c.file}:${c.line}`);
            if (r.callers.length > 15)
                console.log(`      ... and ${r.callers.length - 15} more`);
        }
        console.log();
    }
}
export function context(name, customDbPath, opts = {}) {
    const data = contextData(name, customDbPath, opts);
    if (outputResult(data, 'results', opts))
        return;
    if (data.results.length === 0) {
        console.log(`No function/method/class matching "${name}"`);
        return;
    }
    for (const r of data.results) {
        renderContextResult(r);
    }
}
export function children(name, customDbPath, opts = {}) {
    const data = childrenData(name, customDbPath, opts);
    if (outputResult(data, 'results', opts))
        return;
    if (data.results.length === 0) {
        console.log(`No symbol matching "${name}"`);
        return;
    }
    for (const r of data.results) {
        console.log(`\n${kindIcon(r.kind)} ${r.name}  ${r.file}:${r.line}`);
        if (r.children.length === 0) {
            console.log('  (no children)');
        }
        else {
            for (const c of r.children) {
                console.log(`  ${kindIcon(c.kind)} ${c.name}  :${c.line}`);
            }
        }
    }
}
function renderSignature(sig) {
    if (!sig)
        return;
    console.log('## Type/Shape Info');
    if (sig.params != null)
        console.log(`  Parameters: (${sig.params})`);
    if (sig.returnType)
        console.log(`  Returns: ${sig.returnType}`);
    console.log();
}
function renderComplexity(cx) {
    const miPart = cx.maintainabilityIndex ? ` | MI: ${cx.maintainabilityIndex}` : '';
    console.log('## Complexity');
    console.log(`  Cognitive: ${cx.cognitive} | Cyclomatic: ${cx.cyclomatic} | Max Nesting: ${cx.maxNesting}${miPart}`);
    console.log();
}
function renderSource(source, indent = '  ') {
    console.log('## Source');
    for (const line of source.split('\n')) {
        console.log(`${indent}${line}`);
    }
    console.log();
}
function renderCallees(callees) {
    if (callees.length === 0)
        return;
    console.log(`## Direct Dependencies (${callees.length})`);
    for (const c of callees) {
        const summary = c.summary ? ` — ${c.summary}` : '';
        console.log(`  ${kindIcon(c.kind)} ${c.name}  ${c.file}:${c.line}${summary}`);
        if (c.source) {
            const maxSourceLines = 10;
            for (const line of c.source.split('\n').slice(0, maxSourceLines)) {
                console.log(`    | ${line}`);
            }
        }
    }
    console.log();
}
function renderCallers(callers) {
    if (callers.length === 0)
        return;
    console.log(`## Callers (${callers.length})`);
    for (const c of callers) {
        const via = c.viaHierarchy ? ` (via ${c.viaHierarchy})` : '';
        console.log(`  ${kindIcon(c.kind)} ${c.name}  ${c.file}:${c.line}${via}`);
    }
    console.log();
}
function renderSymbolRefList(label, items) {
    if (items.length === 0)
        return;
    console.log(`## ${label} (${items.length})`);
    for (const s of items) {
        console.log(`  ${kindIcon(s.kind)} ${s.name}  ${s.file}:${s.line}`);
    }
    console.log();
}
function renderRelatedTests(tests) {
    if (tests.length === 0)
        return;
    console.log('## Related Tests');
    const maxTestSourceLines = 20;
    for (const t of tests) {
        console.log(`  ${t.file} — ${t.testCount} tests`);
        for (const tn of t.testNames) {
            console.log(`    - ${tn}`);
        }
        if (t.source) {
            console.log('    Source:');
            for (const line of t.source.split('\n').slice(0, maxTestSourceLines)) {
                console.log(`    | ${line}`);
            }
        }
    }
    console.log();
}
function renderContextResult(r) {
    const lineRange = r.endLine ? `${r.line}-${r.endLine}` : `${r.line}`;
    const roleTag = r.role ? ` [${r.role}]` : '';
    console.log(`\n# ${r.name} (${r.kind})${roleTag} — ${r.file}:${lineRange}\n`);
    renderSignature(r.signature);
    if (r.children && r.children.length > 0) {
        console.log(`## Children (${r.children.length})`);
        for (const c of r.children) {
            console.log(`  ${kindIcon(c.kind)} ${c.name}  :${c.line}`);
        }
        console.log();
    }
    if (r.complexity)
        renderComplexity(r.complexity);
    if (r.source)
        renderSource(r.source);
    renderCallees(r.callees);
    renderCallers(r.callers);
    renderSymbolRefList('Implementors', r.implementors || []);
    renderSymbolRefList('Implements', r.implements || []);
    renderRelatedTests(r.relatedTests);
    if (r.callees.length === 0 && r.callers.length === 0 && r.relatedTests.length === 0) {
        console.log('  (no call edges or tests found — may be invoked dynamically or via re-exports)');
        console.log();
    }
}
function renderExplainSymbolList(label, symbols) {
    if (symbols.length === 0)
        return;
    console.log(`\n## ${label}`);
    for (const s of symbols) {
        const sig = s.signature?.params != null ? `(${s.signature.params})` : '';
        const roleTag = s.role ? ` [${s.role}]` : '';
        const summary = s.summary ? `  -- ${s.summary}` : '';
        console.log(`  ${kindIcon(s.kind)} ${s.name}${sig}${roleTag} :${s.line}${summary}`);
    }
}
function renderFileExplain(r) {
    const publicCount = r.publicApi.length;
    const internalCount = r.internal.length;
    const lineInfo = r.lineCount ? `${r.lineCount} lines, ` : '';
    console.log(`\n# ${r.file}`);
    console.log(`  ${lineInfo}${r.symbolCount} symbols (${publicCount} exported, ${internalCount} internal)`);
    if (r.imports.length > 0) {
        console.log(`  Imports: ${r.imports.map((i) => i.file).join(', ')}`);
    }
    if (r.importedBy.length > 0) {
        console.log(`  Imported by: ${r.importedBy.map((i) => i.file).join(', ')}`);
    }
    renderExplainSymbolList('Exported', r.publicApi);
    renderExplainSymbolList('Internal', r.internal);
    if (r.dataFlow.length > 0) {
        console.log(`\n## Data Flow`);
        for (const df of r.dataFlow) {
            console.log(`  ${df.caller} -> ${df.callees.join(', ')}`);
        }
    }
    console.log();
}
function renderExplainHeader(r, indent) {
    const lineRange = r.endLine ? `${r.line}-${r.endLine}` : `${r.line}`;
    const lineInfo = r.lineCount ? `${r.lineCount} lines` : '';
    const summaryPart = r.summary ? ` | ${r.summary}` : '';
    const roleTag = r.role ? ` [${r.role}]` : '';
    const depthLevel = r._depth || 0;
    const heading = depthLevel === 0 ? '#' : '##'.padEnd(depthLevel + 2, '#');
    console.log(`\n${indent}${heading} ${r.name} (${r.kind})${roleTag}  ${r.file}:${lineRange}`);
    if (lineInfo || r.summary) {
        console.log(`${indent}  ${lineInfo}${summaryPart}`);
    }
    if (r.signature) {
        if (r.signature.params != null)
            console.log(`${indent}  Parameters: (${r.signature.params})`);
        if (r.signature.returnType)
            console.log(`${indent}  Returns: ${r.signature.returnType}`);
    }
}
function renderExplainComplexity(cx, indent) {
    const miPart = cx.maintainabilityIndex ? ` MI=${cx.maintainabilityIndex}` : '';
    console.log(`${indent}  Complexity: cognitive=${cx.cognitive} cyclomatic=${cx.cyclomatic} nesting=${cx.maxNesting}${miPart}`);
}
function renderExplainEdges(r, indent) {
    if (r.callees.length > 0) {
        console.log(`\n${indent}  Calls (${r.callees.length}):`);
        for (const c of r.callees) {
            console.log(`${indent}    ${kindIcon(c.kind)} ${c.name}  ${c.file}:${c.line}`);
        }
    }
    if (r.callers.length > 0) {
        console.log(`\n${indent}  Called by (${r.callers.length}):`);
        for (const c of r.callers) {
            console.log(`${indent}    ${kindIcon(c.kind)} ${c.name}  ${c.file}:${c.line}`);
        }
    }
    if (r.relatedTests.length > 0) {
        const label = r.relatedTests.length === 1 ? 'file' : 'files';
        console.log(`\n${indent}  Tests (${r.relatedTests.length} ${label}):`);
        for (const t of r.relatedTests) {
            console.log(`${indent}    ${t.file}`);
        }
    }
    if (r.callees.length === 0 && r.callers.length === 0) {
        console.log(`${indent}  (no call edges found -- may be invoked dynamically or via re-exports)`);
    }
}
function renderFunctionExplain(r, indent = '') {
    renderExplainHeader(r, indent);
    if (r.complexity)
        renderExplainComplexity(r.complexity, indent);
    renderExplainEdges(r, indent);
    if (r.depDetails && r.depDetails.length > 0) {
        const depthLevel = r._depth || 0;
        console.log(`\n${indent}  --- Dependencies (depth ${depthLevel + 1}) ---`);
        for (const dep of r.depDetails) {
            renderFunctionExplain(dep, `${indent}  `);
        }
    }
    console.log();
}
export function explain(target, customDbPath, opts = {}) {
    const data = explainData(target, customDbPath, opts);
    if (outputResult(data, 'results', opts))
        return;
    if (data.results.length === 0) {
        console.log(`No ${data.kind === 'file' ? 'file' : 'function/symbol'} matching "${target}"`);
        return;
    }
    if (data.kind === 'file') {
        for (const r of data.results) {
            renderFileExplain(r);
        }
    }
    else {
        for (const r of data.results) {
            renderFunctionExplain(r);
        }
    }
}
export function implementations(name, customDbPath, opts = {}) {
    const data = implementationsData(name, customDbPath, opts);
    if (outputResult(data, 'results', opts))
        return;
    if (data.results.length === 0) {
        console.log(`No symbol matching "${name}"`);
        return;
    }
    for (const r of data.results) {
        console.log(`\n${kindIcon(r.kind)} ${r.name}  ${r.file}:${r.line}`);
        if (r.implementors.length === 0) {
            console.log('  (no implementors found)');
        }
        else {
            console.log(`  Implementors (${r.implementors.length}):`);
            for (const impl of r.implementors) {
                console.log(`    ${kindIcon(impl.kind)} ${impl.name}  ${impl.file}:${impl.line}`);
            }
        }
    }
    console.log();
}
export function interfaces(name, customDbPath, opts = {}) {
    const data = interfacesData(name, customDbPath, opts);
    if (outputResult(data, 'results', opts))
        return;
    if (data.results.length === 0) {
        console.log(`No symbol matching "${name}"`);
        return;
    }
    for (const r of data.results) {
        console.log(`\n${kindIcon(r.kind)} ${r.name}  ${r.file}:${r.line}`);
        if (r.interfaces.length === 0) {
            console.log('  (no interfaces/traits found)');
        }
        else {
            console.log(`  Implements (${r.interfaces.length}):`);
            for (const iface of r.interfaces) {
                console.log(`    ${kindIcon(iface.kind)} ${iface.name}  ${iface.file}:${iface.line}`);
            }
        }
    }
    console.log();
}
//# sourceMappingURL=inspect.js.map