import { estimateCost } from './counter.js';
/**
 * Tracks per-tool token consumption and generates optimization reports.
 */
export class OptimizationReporter {
    toolRecords = new Map();
    totalProcessed = 0;
    totalSaved = 0;
    compressionRatioSum = 0;
    compressionCount = 0;
    deduplicationRatioSum = 0;
    deduplicationCount = 0;
    /**
     * Record tokens processed by a tool.
     */
    recordUsage(toolName, tokens) {
        this.totalProcessed += tokens;
        const record = this.getOrCreateRecord(toolName);
        record.totalTokens += tokens;
        record.callCount++;
    }
    /**
     * Record a cache hit for a tool.
     */
    recordCacheHit(toolName, tokensSaved) {
        const record = this.getOrCreateRecord(toolName);
        record.cacheHits++;
        record.tokensSaved += tokensSaved;
        this.totalSaved += tokensSaved;
    }
    /**
     * Record a cache miss for a tool.
     */
    recordCacheMiss(toolName) {
        const record = this.getOrCreateRecord(toolName);
        record.cacheMisses++;
    }
    /**
     * Record compression ratio achieved.
     */
    recordCompression(ratio) {
        this.compressionRatioSum += ratio;
        this.compressionCount++;
    }
    /**
     * Record deduplication ratio achieved.
     */
    recordDeduplication(ratio) {
        this.deduplicationRatioSum += ratio;
        this.deduplicationCount++;
    }
    /**
     * Get records for all tools.
     */
    getToolRecords() {
        return [...this.toolRecords.values()];
    }
    /**
     * Generate full optimization report.
     */
    generateReport(sessionId, cacheStats) {
        const avgCompression = this.compressionCount > 0 ? this.compressionRatioSum / this.compressionCount : 0;
        const avgDedup = this.deduplicationCount > 0 ? this.deduplicationRatioSum / this.deduplicationCount : 0;
        const costWithout = estimateCost(this.totalProcessed, 'claude-sonnet').totalCostUsd;
        const costWith = estimateCost(this.totalProcessed - this.totalSaved, 'claude-sonnet').totalCostUsd;
        return {
            sessionId,
            totalTokensProcessed: this.totalProcessed,
            totalTokensSaved: this.totalSaved,
            savingsPercent: this.totalProcessed > 0 ? (this.totalSaved / this.totalProcessed) * 100 : 0,
            cacheStats,
            compressionRatio: avgCompression,
            deduplicationRatio: avgDedup,
            costWithoutOptimization: costWithout,
            costWithOptimization: costWith,
        };
    }
    /**
     * Format report as human-readable text.
     */
    formatReport(report) {
        const lines = [
            '## Token Optimization Report',
            '',
            `Session: ${report.sessionId}`,
            `Total tokens processed: ${String(report.totalTokensProcessed)}`,
            `Total tokens saved: ${String(report.totalTokensSaved)}`,
            `Savings: ${report.savingsPercent.toFixed(1)}%`,
            '',
            '### Cache Performance',
            `Hit rate: ${(report.cacheStats.hitRate * 100).toFixed(1)}%`,
            `Hits: ${String(report.cacheStats.hits)} | Misses: ${String(report.cacheStats.misses)}`,
            `Entries: ${String(report.cacheStats.entries)}`,
            '',
            '### Optimization Ratios',
            `Compression: ${(report.compressionRatio * 100).toFixed(1)}%`,
            `Deduplication: ${(report.deduplicationRatio * 100).toFixed(1)}%`,
            '',
            '### Cost Impact',
            `Without optimization: $${report.costWithoutOptimization.toFixed(6)}`,
            `With optimization: $${report.costWithOptimization.toFixed(6)}`,
        ];
        const toolRecords = this.getToolRecords();
        if (toolRecords.length > 0) {
            lines.push('', '### Per-Tool Breakdown');
            for (const record of toolRecords) {
                lines.push(`- ${record.toolName}: ${String(record.totalTokens)} tokens, ` +
                    `${String(record.callCount)} calls, ` +
                    `${String(record.tokensSaved)} saved`);
            }
        }
        return lines.join('\n');
    }
    /**
     * Reset all tracking data.
     */
    reset() {
        this.toolRecords.clear();
        this.totalProcessed = 0;
        this.totalSaved = 0;
        this.compressionRatioSum = 0;
        this.compressionCount = 0;
        this.deduplicationRatioSum = 0;
        this.deduplicationCount = 0;
    }
    // --- Internal ---
    getOrCreateRecord(toolName) {
        let record = this.toolRecords.get(toolName);
        if (!record) {
            record = {
                toolName,
                totalTokens: 0,
                callCount: 0,
                cacheHits: 0,
                cacheMisses: 0,
                tokensSaved: 0,
            };
            this.toolRecords.set(toolName, record);
        }
        return record;
    }
}
//# sourceMappingURL=reporter.js.map