"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.aggregateAndLogEvalUsage = aggregateAndLogEvalUsage;
const decimal_js_1 = __importDefault(require("decimal.js"));
const billing_logger_1 = __importDefault(require("../billing/billing-logger"));
const createEmptyTotals = () => ({
    prompt: new decimal_js_1.default(0),
    completion: new decimal_js_1.default(0),
    total: new decimal_js_1.default(0),
    cached: new decimal_js_1.default(0),
    duration: new decimal_js_1.default(0),
});
/**
 * Aggregate evaluation cost and token usage per model (including Deepgram duration)
 * and log a single billing line per model for functional or security evaluations.
 *
 * Returns total cost and token totals across all models so callers can reuse them
 * (e.g., for metric billing).
 */
async function aggregateAndLogEvalUsage({ evalType, workspaceId, evalId, evalResults, baseMetadata = {}, }) {
    const totalTokens = createEmptyTotals();
    let totalCost = new decimal_js_1.default(0);
    const perModel = {};
    const ensureBucket = (modelName) => {
        if (!perModel[modelName]) {
            perModel[modelName] = {
                cost: new decimal_js_1.default(0),
                tokenUsage: createEmptyTotals(),
            };
        }
        return perModel[modelName];
    };
    evalResults?.forEach?.((result) => {
        const grading = result?.gradingResult;
        grading?.componentResults?.forEach?.((componentResult) => {
            const tokens = componentResult?.tokensUsed;
            if (!componentResult || !tokens) {
                return;
            }
            const hasAnyTokenUsage = (typeof tokens.total === 'number' && tokens.total > 0) ||
                (typeof tokens.prompt === 'number' && tokens.prompt > 0) ||
                (typeof tokens.completion === 'number' && tokens.completion > 0) ||
                (typeof tokens.cached === 'number' && tokens.cached > 0) ||
                (typeof tokens.duration === 'number' && tokens.duration > 0);
            const costNumber = typeof grading.cost === 'number' ? grading.cost : 0;
            if (!hasAnyTokenUsage) {
                return;
            }
            const modelName = typeof tokens.model === 'string' && tokens.model ? tokens.model : 'default';
            const modelBucket = ensureBucket(modelName);
            // Aggregate cost
            totalCost = totalCost.plus(costNumber);
            modelBucket.cost = modelBucket.cost.plus(costNumber);
            // Aggregate token usage for this model and global totals
            const addToken = (key, value) => {
                if (typeof value !== 'number' || Number.isNaN(value)) {
                    return;
                }
                totalTokens[key] = totalTokens[key].plus(value);
                modelBucket.tokenUsage[key] = modelBucket.tokenUsage[key].plus(value);
            };
            addToken('prompt', tokens.prompt);
            addToken('completion', tokens.completion);
            addToken('total', tokens.total);
            addToken('cached', tokens.cached);
            addToken('duration', tokens.duration);
            // Special handling for Deepgram: duration-only bucket under "deepgram"
            if (typeof tokens.duration === 'number' && tokens.duration > 0) {
                const deepgramBucket = ensureBucket('deepgram');
                deepgramBucket.tokenUsage.duration = deepgramBucket.tokenUsage.duration.plus(tokens.duration);
            }
        });
    });
    // Log one line per model
    const logPromises = [];
    Object.entries(perModel)?.forEach?.(([modelName, bucket]) => {
        const usage = bucket.tokenUsage;
        const hasUsage = usage.total.gt(0) ||
            usage.prompt.gt(0) ||
            usage.completion.gt(0) ||
            usage.cached.gt(0) ||
            usage.duration.gt(0) ||
            bucket.cost.gt(0);
        if (!hasUsage) {
            return;
        }
        const tokenUsageForLog = {
            prompt: usage.prompt.toNumber(),
            completion: usage.completion.toNumber(),
            total: usage.total.toNumber(),
            cached: usage.cached.toNumber(),
            duration: usage.duration.toNumber(),
        };
        if (evalType === 'functional') {
            logPromises.push(billing_logger_1.default.logFunctionEvalUsage({
                workspaceId,
                functionEvalId: evalId,
                cost: bucket.cost.toNumber(),
                tokenUsage: tokenUsageForLog,
                metadata: { ...baseMetadata },
                model: modelName,
            }));
        }
        else {
            logPromises.push(billing_logger_1.default.logSecurityEvalUsage({
                workspaceId,
                securityEvalId: evalId,
                cost: bucket.cost.toNumber(),
                tokenUsage: tokenUsageForLog,
                metadata: { ...baseMetadata },
                model: modelName,
            }));
        }
    });
    if (logPromises.length > 0) {
        await Promise.allSettled(logPromises);
    }
    return { totalCost, totalTokens };
}
//# sourceMappingURL=evalBilling.js.map