export function emptyImpactMap() {
    return { files: [], symbols: [], edges: [], truncated: false };
}
export function clampConfidence(value) {
    return Math.max(0, Math.min(1, Number.isFinite(value) ? value : 0));
}
export function estimateImpactBudget(tokenBudget) {
    if (tokenBudget <= 0) {
        return 1;
    }
    return Math.max(1, Math.min(50, Math.floor(tokenBudget / 120)));
}
export function mergeImpactMaps(maps, tokenBudget) {
    const maxFiles = estimateImpactBudget(tokenBudget);
    const files = new Map();
    const symbols = new Map();
    const edges = new Map();
    let sourceCount = 0;
    for (const map of maps) {
        for (const file of map.files) {
            sourceCount += 1;
            const existing = files.get(file.path);
            if (!existing || existing.confidence < file.confidence) {
                files.set(file.path, { ...file, confidence: clampConfidence(file.confidence) });
            }
        }
        for (const symbol of map.symbols) {
            symbols.set(`${symbol.path}:${symbol.name}:${String(symbol.line ?? '')}`, {
                ...symbol,
                confidence: clampConfidence(symbol.confidence),
            });
        }
        for (const edge of map.edges) {
            edges.set(`${edge.from}->${edge.to}:${edge.type}`, edge);
        }
    }
    const rankedFiles = [...files.values()].sort((a, b) => b.confidence - a.confidence);
    const selectedFiles = rankedFiles.slice(0, maxFiles);
    const selectedPaths = new Set(selectedFiles.map((file) => file.path));
    return {
        files: selectedFiles,
        symbols: [...symbols.values()].filter((symbol) => selectedPaths.has(symbol.path)),
        edges: [...edges.values()].filter((edge) => selectedPaths.has(edge.from) || selectedPaths.has(edge.to)),
        truncated: rankedFiles.length < sourceCount || rankedFiles.length > selectedFiles.length,
    };
}
//# sourceMappingURL=impact-map.js.map