import { METRIC_RANGE_VALUES } from "./prometheus.js";
const MAX_LIMIT = 500;
function parseStreams(streams) {
    const entries = [];
    for (const stream of streams) {
        for (const [nsTs, line] of stream.values) {
            // Loki timestamps are nanoseconds
            const timestamp = parseInt(nsTs, 10) / 1e9;
            entries.push({ timestamp, line });
        }
    }
    return entries.sort((a, b) => a.timestamp - b.timestamp);
}
export class LokiClient {
    baseUrl;
    constructor(baseUrl) {
        this.baseUrl = baseUrl.replace(/\/$/, "");
    }
    async queryRange(logQuery, since, limit) {
        const cappedLimit = Math.min(limit, MAX_LIMIT);
        const duration = METRIC_RANGE_VALUES[since] ?? METRIC_RANGE_VALUES.ONE_HOUR;
        const end = Math.floor(Date.now() / 1000);
        const durationSeconds = parseDurationToSeconds(duration);
        const start = end - durationSeconds;
        const params = new URLSearchParams({
            query: logQuery,
            start: String(start),
            end: String(end),
            limit: String(cappedLimit),
        });
        try {
            const res = await fetch(`${this.baseUrl}/loki/api/v1/query_range?${params.toString()}`);
            if (!res.ok) {
                return [];
            }
            const json = (await res.json());
            if (json.status !== "success" || json.data.resultType !== "streams") {
                return [];
            }
            return parseStreams(json.data.result);
        }
        catch {
            return [];
        }
    }
    async logs(tenantId, service, since = "ONE_HOUR", limit = 100) {
        let query = `{namespace="${tenantId}"}`;
        if (service) {
            query = `{namespace="${tenantId}", container="${service.toLowerCase()}"}`;
        }
        return this.queryRange(query, since, limit);
    }
    async errorLogs(tenantId, since = "ONE_HOUR", limit = 100) {
        const query = `{namespace="${tenantId}"} |= "error" | json | level="error"`;
        return this.queryRange(query, since, limit);
    }
}
function parseDurationToSeconds(duration) {
    const match = duration.match(/^(\d+)([mhd])$/);
    if (!match)
        return 3600;
    const value = parseInt(match[1], 10);
    switch (match[2]) {
        case "m":
            return value * 60;
        case "h":
            return value * 3600;
        case "d":
            return value * 86400;
        default:
            return 3600;
    }
}
