import { caseRunAccepted } from "./transport.ts";

export function createHarnessRLHttpApp(options: { service: ReturnType<typeof import("./service.ts")["createHarnessRLService"]> }) {
  return {
    async fetch(request: Request) {
      const url = new URL(request.url);
      try {
        if (url.pathname === "/healthz" || url.pathname === "/health/live") return json(200, { ok: true, serviceId: "hwlab-harnessrl-api" });
        if (url.pathname === "/readyz" || url.pathname === "/health/ready") return json(200, await options.service.health());
        if (url.pathname === "/v1/caserun" && request.method === "GET") return json(200, { ok: true, contractVersion: "hwlab-caserun-web-v1", casesRoute: "/v1/caserun/cases", runsRoute: "/v1/caserun/runs", executionAuthority: "temporal", registryAuthority: "postgresql" });
        if (url.pathname === "/v1/caserun/cases" && request.method === "GET") {
          const cases = await options.service.listCases();
          return json(200, { ok: true, contractVersion: "hwlab-caserun-cases-v1", count: cases.length, cases });
        }
        if (url.pathname === "/v1/caserun/runs" && request.method === "POST") {
          const body = await bodyObject(request);
          const record = await options.service.submit({ caseId: String(body.caseId ?? ""), runId: body.runId ? String(body.runId) : undefined, runtimeApiUrl: runtimeApiUrl(request) });
          return json(202, caseRunAccepted(record));
        }
        if (url.pathname === "/v1/caserun/runs" && request.method === "GET") {
          return json(200, await options.service.listRuns({
            status: url.searchParams.get("status") ?? undefined,
            limit: url.searchParams.get("limit") ?? undefined,
            cursor: url.searchParams.get("cursor") ?? undefined
          }));
        }
        const match = /^\/v1\/caserun\/runs\/([^/]+)(?:\/(events|aggregate|cancel))?$/u.exec(url.pathname);
        if (match) {
          const runId = decodeURIComponent(match[1]);
          const suffix = match[2] ?? "";
          if (!suffix && request.method === "GET") return json(200, await options.service.getRun(runId));
          if (suffix === "events" && request.method === "GET") return json(200, await options.service.events(runId));
          if (suffix === "aggregate" && request.method === "GET") return json(200, await options.service.aggregate(runId));
          if (suffix === "cancel" && request.method === "POST") return json(202, await options.service.cancel(runId));
          return json(405, errorBody("method_not_allowed", suffix === "cancel" ? "POST required" : "GET required"));
        }
        return json(404, errorBody("caserun_route_not_found", "CaseRun REST route is not implemented"));
      } catch (error: any) {
        const code = error?.code ?? "harnessrl_error";
        const status = code.includes("not_found") ? 404 : code.startsWith("invalid_") ? 400 : 500;
        return json(status, errorBody(code, error?.message ?? String(error), error?.details));
      }
    },
    close: () => options.service.close()
  };
}

async function bodyObject(request: Request) { const body = await request.json().catch(() => null); if (!body || typeof body !== "object" || Array.isArray(body)) throw Object.assign(new Error("JSON object body is required"), { code: "invalid_json" }); return body as Record<string, unknown>; }
function runtimeApiUrl(request: Request) { const url = new URL(request.url); return `${url.protocol}//${url.host}`; }
function errorBody(code: string, message: string, details?: unknown) { return { ok: false, error: { code, message, details } }; }
function json(status: number, body: unknown) { return Response.json(body, { status, headers: { "cache-control": "no-store" } }); }
