/**
 * EvalClient
 *
 * Client for the eval service API: projects, test suites, test cases, runs, and reports.
 */
export class EvalClient {
    constructor(baseUrl, headers) {
        this.projects = {
            create: (data) => this.request("/api/eval/projects", {
                method: "POST",
                body: JSON.stringify(data),
            }),
            list: () => this.request("/api/eval/projects"),
            get: (id) => this.request(`/api/eval/projects/${id}`),
            update: (id, patch) => this.request(`/api/eval/projects/${id}`, {
                method: "PUT",
                body: JSON.stringify(patch),
            }),
            delete: (id) => this.request(`/api/eval/projects/${id}`, { method: "DELETE" }),
            suites: {
                create: (projectId, data) => this.request(`/api/eval/projects/${projectId}/suites`, {
                    method: "POST",
                    body: JSON.stringify(data),
                }),
                update: (projectId, suiteId, patch) => this.request(`/api/eval/projects/${projectId}/suites/${suiteId}`, {
                    method: "PUT",
                    body: JSON.stringify(patch),
                }),
                delete: (projectId, suiteId) => this.request(`/api/eval/projects/${projectId}/suites/${suiteId}`, { method: "DELETE" }),
                cases: {
                    list: (projectId, suiteId) => this.request(`/api/eval/projects/${projectId}/suites/${suiteId}/cases`),
                    create: (projectId, suiteId, data) => this.request(`/api/eval/projects/${projectId}/suites/${suiteId}/cases`, {
                        method: "POST",
                        body: JSON.stringify(data),
                    }),
                    update: (projectId, suiteId, caseId, patch) => this.request(`/api/eval/projects/${projectId}/suites/${suiteId}/cases/${caseId}`, {
                        method: "PUT",
                        body: JSON.stringify(patch),
                    }),
                    delete: (projectId, suiteId, caseId) => this.request(`/api/eval/projects/${projectId}/suites/${suiteId}/cases/${caseId}`, { method: "DELETE" }),
                },
            },
        };
        this.runs = {
            start: (projectId) => this.request(`/api/eval/projects/${projectId}/runs`, { method: "POST" }),
            list: (opts) => {
                const params = new URLSearchParams();
                if (opts?.projectId)
                    params.set("project_id", opts.projectId);
                if (opts?.status)
                    params.set("status", opts.status);
                const qs = params.toString();
                return this.request(`/api/eval/runs${qs ? `?${qs}` : ""}`);
            },
            get: (id) => this.request(`/api/eval/runs/${id}`),
            abort: (id) => this.request(`/api/eval/runs/${id}/abort`, { method: "POST" }),
            delete: (id) => this.request(`/api/eval/runs/${id}`, { method: "DELETE" }),
            stream: (id) => this.streamRun(id),
        };
        this.reports = {
            project: (projectId) => this.request(`/api/eval/reports/projects/${projectId}`),
        };
        this.baseUrl = baseUrl;
        this.headers = headers;
    }
    async request(path, opts) {
        const res = await fetch(`${this.baseUrl}${path}`, {
            ...opts,
            headers: { ...this.headers, ...opts?.headers },
        });
        const json = (await res.json());
        if (!json.success)
            throw new Error(json.message);
        return json.data;
    }
    async *streamRun(id) {
        const res = await fetch(`${this.baseUrl}/api/eval/runs/${id}/stream`, {
            headers: this.headers,
        });
        if (!res.ok || !res.body)
            throw new Error("Stream connection failed");
        const reader = res.body.getReader();
        const decoder = new TextDecoder();
        let buffer = "";
        while (true) {
            const { done, value } = await reader.read();
            if (done)
                break;
            buffer += decoder.decode(value, { stream: true });
            const lines = buffer.split("\n");
            buffer = lines.pop() || "";
            let eventType = "";
            for (const line of lines) {
                if (line.startsWith("event: ")) {
                    eventType = line.slice(7);
                }
                else if (line.startsWith("data: ")) {
                    try {
                        const data = JSON.parse(line.slice(6));
                        yield { type: eventType, runId: id, data };
                    }
                    catch {
                        // skip parse errors
                    }
                }
            }
        }
    }
}
//# sourceMappingURL=eval.js.map