"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildUsageResponseFromCliproxyMainLog = exports.buildUsageResponseFromCliproxyLogLines = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const path_resolver_1 = require("../config/path-resolver");
const usage_compatibility_transformer_1 = require("./usage-compatibility-transformer");
function unquote(value) {
    return value.trim().replace(/^['"]|['"]$/g, '');
}
function extractTimestamp(line) {
    const isoTimestamp = line.match(/\d{4}-\d{2}-\d{2}T[^\s\]]+/)?.[0];
    if (isoTimestamp) {
        return isoTimestamp.replace(/[,\]]+$/, '');
    }
    const bracketedTimestamp = line
        .match(/^\[(\d{4}-\d{2}-\d{2})[ T](\d{2}:\d{2}:\d{2})\]/)
        ?.slice(1, 3);
    if (!bracketedTimestamp) {
        return undefined;
    }
    const [datePart, timePart] = bracketedTimestamp;
    const [year, month, day] = datePart.split('-').map(Number);
    const [hour, minute, second] = timePart.split(':').map(Number);
    return new Date(year, month - 1, day, hour, minute, second).toISOString();
}
function extractRequestId(line) {
    const explicitRequestId = line.match(/\b(?:request[_-]?id|req[_-]?id|rid)[=:]\s*([A-Za-z0-9._:-]+)/i)?.[1];
    if (explicitRequestId) {
        return explicitRequestId;
    }
    const bracketedRequestId = line.match(/^\[[^\]]+\]\s+\[([^\]]+)\]/)?.[1]?.trim();
    return bracketedRequestId && bracketedRequestId !== '--------' ? bracketedRequestId : undefined;
}
function parseOAuthSelection(line) {
    const match = line.match(/Use OAuth\s+provider=([^\s]+)\s+auth_file=("[^"]+"|'[^']+'|[^\s]+)\s+for model\s+("[^"]+"|'[^']+'|[^\s]+)/i);
    if (!match) {
        return null;
    }
    return {
        timestamp: extractTimestamp(line),
        provider: unquote(match[1] ?? 'unknown'),
        authFile: unquote(match[2] ?? 'unknown'),
        model: unquote(match[3] ?? 'unknown'),
        requestId: extractRequestId(line),
    };
}
function parseProviderCompletion(line) {
    const match = line.match(/\b(?:POST|GET)\s+"?\/api\/provider\/([^/"\s]+)\//i);
    if (!match) {
        return null;
    }
    return {
        timestamp: extractTimestamp(line),
        provider: unquote(match[1] ?? 'unknown'),
        requestId: extractRequestId(line),
        failed: /\b(?:failed|failure|error)\b/i.test(line) ||
            /\bstatus[=:]\s*[45]\d\d\b/i.test(line) ||
            /\s[45]\d\d(?:\s|$)/.test(line),
    };
}
function addPendingRequest(pending, byRequestId, byProvider) {
    if (pending.requestId) {
        const previous = byRequestId.get(pending.requestId);
        if (previous) {
            const previousProviderQueue = byProvider.get(previous.provider) ?? [];
            byProvider.set(previous.provider, previousProviderQueue.filter((entry) => entry !== previous));
        }
        byRequestId.set(pending.requestId, pending);
    }
    const providerQueue = byProvider.get(pending.provider) ?? [];
    providerQueue.push(pending);
    byProvider.set(pending.provider, providerQueue);
}
function takePendingRequest(completion, byRequestId, byProvider) {
    const byId = completion.requestId ? byRequestId.get(completion.requestId) : undefined;
    if (byId) {
        byRequestId.delete(completion.requestId ?? '');
        const providerQueue = byProvider.get(byId.provider) ?? [];
        byProvider.set(byId.provider, providerQueue.filter((entry) => entry !== byId));
        return byId;
    }
    const providerQueue = byProvider.get(completion.provider) ?? [];
    const next = providerQueue.shift();
    byProvider.set(completion.provider, providerQueue);
    if (next?.requestId) {
        byRequestId.delete(next.requestId);
    }
    return next ?? null;
}
function buildUsageResponseFromCliproxyLogLines(lines) {
    const pendingByRequestId = new Map();
    const pendingByProvider = new Map();
    const records = [];
    for (const line of lines) {
        const selection = parseOAuthSelection(line);
        if (selection) {
            addPendingRequest(selection, pendingByRequestId, pendingByProvider);
            continue;
        }
        const completion = parseProviderCompletion(line);
        if (!completion) {
            continue;
        }
        const pending = takePendingRequest(completion, pendingByRequestId, pendingByProvider);
        if (!pending) {
            continue;
        }
        records.push({
            timestamp: completion.timestamp ?? pending.timestamp ?? '1970-01-01T00:00:00.000Z',
            provider: pending.provider,
            model: pending.model,
            source: `provider=${pending.provider} auth_file=${pending.authFile}`,
            auth_index: pending.authFile,
            request_id: completion.requestId ?? pending.requestId,
            failed: completion.failed,
            tokens: {},
        });
    }
    return (0, usage_compatibility_transformer_1.buildUsageResponseFromQueueRecords)(records);
}
exports.buildUsageResponseFromCliproxyLogLines = buildUsageResponseFromCliproxyLogLines;
const MAX_LOG_BYTES = 2 * 1024 * 1024;
function readLogFile(filePath) {
    if (!fs.existsSync(filePath)) {
        return null;
    }
    const stats = fs.statSync(filePath);
    if (stats.size > MAX_LOG_BYTES) {
        return null;
    }
    return fs.readFileSync(filePath, 'utf-8');
}
function buildUsageResponseFromCliproxyMainLog() {
    const logPath = path.join((0, path_resolver_1.getCliproxyWritablePath)(), 'logs', 'main.log');
    const contents = readLogFile(logPath);
    if (!contents) {
        return null;
    }
    const response = buildUsageResponseFromCliproxyLogLines(contents.split(/\r?\n/));
    return (0, usage_compatibility_transformer_1.hasUsageDetails)(response) ? response : null;
}
exports.buildUsageResponseFromCliproxyMainLog = buildUsageResponseFromCliproxyMainLog;
//# sourceMappingURL=oauth-usage-log-transformer.js.map