import { countTokens } from './counter.js';
/**
 * Compress content using the specified strategy.
 */
export function compress(content, strategy, options) {
    const originalTokens = countTokens(content).tokens;
    const maxLines = options?.maxLines ?? 20;
    let compressed;
    switch (strategy) {
        case 'truncation':
            compressed = applyTruncation(content, maxLines);
            break;
        case 'extraction':
            compressed = applyExtraction(content);
            break;
        case 'summary':
            compressed = applySummary(content);
            break;
        case 'headTail':
            compressed = applyHeadTail(content, maxLines);
            break;
        case 'codeOnly':
            compressed = applyCodeOnly(content);
            break;
        case 'structureOnly':
            compressed = applyStructureOnly(content);
            break;
    }
    const compressedTokens = countTokens(compressed).tokens;
    return {
        compressed,
        originalTokens,
        compressedTokens,
        ratio: originalTokens > 0 ? 1 - compressedTokens / originalTokens : 0,
        strategy,
    };
}
/**
 * Auto-select best compression strategy based on content heuristics.
 */
export function selectStrategy(content) {
    const lines = content.split('\n');
    const codeIndicators = lines.filter((l) => /^\s*(export|import|function|class|interface|type |const |let |var |def |fn |pub |func )/.test(l)).length;
    const codeRatio = lines.length > 0 ? codeIndicators / lines.length : 0;
    if (codeRatio > 0.3) {
        return 'extraction';
    }
    if (lines.length > 100) {
        return 'headTail';
    }
    if (countTokens(content).tokens > 2000) {
        return 'truncation';
    }
    return 'summary';
}
/**
 * Apply multiple strategies in chain, returning the best result.
 */
export function compressChain(content, strategies) {
    let current = content;
    const totalOriginal = countTokens(content).tokens;
    let lastStrategy = strategies[0] ?? 'truncation';
    for (const strategy of strategies) {
        const result = compress(current, strategy);
        current = result.compressed;
        lastStrategy = strategy;
    }
    const finalTokens = countTokens(current).tokens;
    return {
        compressed: current,
        originalTokens: totalOriginal,
        compressedTokens: finalTokens,
        ratio: totalOriginal > 0 ? 1 - finalTokens / totalOriginal : 0,
        strategy: lastStrategy,
    };
}
// --- Internal strategies ---
function applyTruncation(content, maxLines) {
    const lines = content.split('\n');
    if (lines.length <= maxLines * 2) {
        return content;
    }
    const head = lines.slice(0, maxLines);
    const tail = lines.slice(-maxLines);
    const omitted = lines.length - maxLines * 2;
    return [...head, `[... ${String(omitted)} lines omitted ...]`, ...tail].join('\n');
}
function applyHeadTail(content, maxLines) {
    return applyTruncation(content, maxLines);
}
function applyExtraction(content) {
    const lines = content.split('\n');
    const extracted = lines.filter((line) => /^\s*(export|import|function|class|interface|type |const |def |fn |pub |func |struct |enum )/.test(line) ||
        /^\s*\*/.test(line) ||
        /^\s*\/\//.test(line) ||
        line.trim() === '');
    return extracted.length > 0 ? extracted.join('\n') : content.slice(0, 500);
}
function applySummary(content) {
    const lines = content.split('\n').filter((l) => l.trim().length > 0);
    const bullets = [];
    for (const line of lines) {
        if (line.startsWith('#') || line.startsWith('##')) {
            bullets.push(`- ${line.replace(/^#+\s*/, '')}`);
        }
        else if (/^\s*[-*]\s/.test(line)) {
            bullets.push(line);
        }
        else if (bullets.length < 10 && line.trim().length > 20) {
            bullets.push(`- ${line.trim().slice(0, 100)}`);
        }
        if (bullets.length >= 15) {
            break;
        }
    }
    return bullets.length > 0 ? bullets.join('\n') : content.slice(0, 300);
}
function applyCodeOnly(content) {
    const lines = content.split('\n');
    const codeBlocks = [];
    let inBlock = false;
    for (const line of lines) {
        if (line.trim().startsWith('```')) {
            inBlock = !inBlock;
            continue;
        }
        if (inBlock) {
            codeBlocks.push(line);
        }
    }
    // If no fenced blocks, treat lines with code indicators as code
    if (codeBlocks.length === 0) {
        return (lines
            .filter((l) => /^\s*(export|import|function|class|const |let |def |fn |return )/.test(l) ||
            /[{};()=>]/.test(l))
            .join('\n') || content.slice(0, 300));
    }
    return codeBlocks.join('\n');
}
function applyStructureOnly(content) {
    const lines = content.split('\n');
    return (lines
        .filter((line) => line.startsWith('#') ||
        /^\s*(export|function|class|interface|type |struct |enum |def |fn )/.test(line) ||
        /^\s*\}/.test(line))
        .join('\n') || content.slice(0, 200));
}
//# sourceMappingURL=context-compressor.js.map