export class PrometheusClient {
    config;
    httpClient;
    constructor(config, httpClient = fetch){
        this.config = config;
        this.httpClient = httpClient;
    }
    async querySingleValue(query, time = new Date()) {
        const resp = await this.queryRaw(query, time);
        if (resp.status === 'success') {
            if (resp.data.resultType === 'vector') {
                if (resp.data.result.length === 0) {
                    return 0;
                }
                const [_, value] = resp.data.result[0].value;
                return parseFloat(value);
            }
        }
        throw new TypeError('Unsupported response body', {
            cause: JSON.stringify(resp)
        });
    }
    queryRaw(query, time = new Date()) {
        const searchParams = new URLSearchParams();
        searchParams.set('query', query);
        searchParams.set('time', String(Math.trunc(time.getTime() / 1000)));
        searchParams.set('limit', '10');
        return this.callPrometheus('query', searchParams);
    }
    queryRangeRaw(query, step, start, end = new Date()) {
        const searchParams = new URLSearchParams();
        searchParams.set('query', query);
        searchParams.set('step', step);
        searchParams.set('start', String(Math.trunc(start.getTime() / 1000)));
        searchParams.set('end', String(Math.trunc(end.getTime() / 1000)));
        searchParams.set('limit', '10');
        return this.callPrometheus('query_range', searchParams);
    }
    async callPrometheus(api, searchParams) {
        const url = new URL('api/v1/' + api, this.config.server);
        for (const [name, value] of searchParams){
            url.searchParams.append(name, value);
        }
        const resp = await this.httpClient(url, {
            method: 'GET'
        });
        if (!resp.ok || resp.status !== 200) {
            throw new Error('Invalid HTTP response from Prometheus', {
                cause: {
                    url,
                    status: resp.status,
                    statusText: resp.statusText
                }
            });
        }
        const body = await resp.json();
        if ('status' in body && (body.status === 'error' || body.status === 'success')) {
            return body;
        }
        throw new Error('Invalid response from Prometheus', {
            cause: {
                url,
                body
            }
        });
    }
}
