/**
 * Pipeline step: Deliver results to a callback URL.
 *
 * After the pipeline completes and the report is published, this step
 * POSTs the results to the caller's callback URL. Used for API-triggered
 * evaluations where the caller wants push-based result delivery.
 *
 * This step is always optional — callback failure never blocks the pipeline.
 * The result is already in the Content Lake (system of record).
 *
 * @see packages/eval/src/pipeline/callback-delivery.ts
 * @see docs/design-docs/api-service-gateway.md
 */
import { readFileSync } from "fs";
import { resolve } from "path";
import { assoc, } from "../../_vendor/ailf-core/index.js";
import { deliverCallback, } from "../../pipeline/callback-delivery.js";
export class CallbackStep {
    callback;
    jobId;
    name = "callback-delivery";
    optional = true;
    constructor(callback, jobId) {
        this.callback = callback;
        this.jobId = jobId;
    }
    check() {
        const issues = [];
        if (!this.callback.url) {
            issues.push({
                message: "Callback URL is required",
                severity: "error",
                source: "callback-delivery",
            });
        }
        return issues;
    }
    async execute(ctx, state) {
        const start = Date.now();
        const { rootDir } = ctx.config;
        // Read score summary
        let summary;
        try {
            const summaryPath = resolve(rootDir, "results", "latest", "score-summary.json");
            summary = JSON.parse(readFileSync(summaryPath, "utf-8"));
        }
        catch (err) {
            return {
                durationMs: Date.now() - start,
                error: `Failed to read score-summary.json for callback: ${err instanceof Error ? err.message : String(err)}`,
                status: "failed",
            };
        }
        // Deliver callback — read reportId from pipeline state (set by PublishReportStep)
        ctx.logger.info(`Delivering results to ${this.callback.url}`);
        const callbackPayload = {
            deliveredAt: new Date().toISOString(),
            jobId: this.jobId,
            reportId: state.reportId,
            summary,
        };
        // W0050 — callbackRequest/callbackResponse are per-entry artifacts
        // keyed by the callback target URL (the `name` slot on the association).
        const callbackName = this.callback.url;
        await ctx.artifactWriter.emit("callbackRequest", assoc(ctx, { name: callbackName }), callbackPayload);
        const result = await deliverCallback(this.callback, callbackPayload);
        await ctx.artifactWriter.emit("callbackResponse", assoc(ctx, { name: callbackName }), {
            ok: result.ok,
            attempts: result.attempts,
            error: result.error,
        });
        if (result.ok) {
            return {
                durationMs: Date.now() - start,
                status: "success",
                summary: `Callback delivered to ${this.callback.url} (${result.attempts} attempt${result.attempts === 1 ? "" : "s"})`,
            };
        }
        // Callback failure is not critical — log warning
        ctx.logger.warn(`Callback delivery failed after ${result.attempts} attempts: ${result.error}`);
        return {
            durationMs: Date.now() - start,
            error: `Callback delivery failed: ${result.error}`,
            status: "failed",
        };
    }
}
