/**
 * # cli/backend/sse — the CLI face of the shared SSE transport leaf (kestrel-telx.3 / bsn8).
 *
 * The framing + opaque-cursor resume loop itself lives in the LIBRARY-SAFE leaf
 * {@link ../../client/sse-transport.ts} — ONE loop shared by the SDK's {@link ../../client/index.ts
 * KestrelClient} and, through this module, the CLI's {@link ./remote.ts RemoteBackend}. This file is
 * the thin CLI adapter: it supplies the fail-closed error factories the leaf requires as {@link CliError}
 * (the CLI's error contract), so a CLI caller uses `consumeSseStream` with the same options it always
 * did and still fails closed as `CliError`. The leaf is error-agnostic; the CLI's error TYPE lives here.
 *
 *   - fail closed: an `event:` outside the caller's vocabulary → {@link unknownEvent}
 *     (SSE_PROTOCOL_VIOLATION); a bad HTTP status / budget exhaustion → {@link httpErr}.
 *   - resume + framing + the reconnect budget are the leaf's ({@link MAX_RECONNECTS}), re-exported here.
 *
 * The web `ReadableStream` on `response.body` → node AND bun compatible.
 */

import { CliError, EXIT } from "../errors.ts";
import {
  MAX_RECONNECTS,
  consumeSseStream as consumeSseStreamCore,
  parseSSE,
} from "../../client/sse-transport.ts";
import type { FetchLike, SseFrameOutcome, SseStreamOptions as CoreSseStreamOptions } from "../../client/sse-transport.ts";

export { MAX_RECONNECTS, parseSSE };
export type { FetchLike, SseFrameOutcome };

/** The CLI-flavoured stream options: the fail-closed error factories the leaf requires default to
 *  {@link CliError}, so a CLI caller need not supply them (it may override to customize a message). */
export type SseStreamOptions = Omit<CoreSseStreamOptions, "httpError" | "unknownEventError"> &
  Partial<Pick<CoreSseStreamOptions, "httpError" | "unknownEventError">>;

/** Read an event stream to the caller's terminal frame over the shared leaf, defaulting the
 *  fail-closed errors to the CLI's {@link CliError} taxonomy. */
export function consumeSseStream(opts: SseStreamOptions): Promise<void> {
  return consumeSseStreamCore({
    ...opts,
    httpError: opts.httpError ?? httpErr,
    unknownEventError: opts.unknownEventError ?? unknownEvent,
  });
}

/** Map an HTTP status onto a fail-closed {@link CliError} with a stable `HTTP_<status>` code. */
export function httpErr(status: number, m: string): CliError {
  const exit = status === 404 ? EXIT.NOT_FOUND : status >= 500 ? EXIT.RUNTIME_UNAVAILABLE : EXIT.GENERIC;
  return new CliError({ code: `HTTP_${status}`, exit, message: `${m} (HTTP ${status})` });
}

/** Fail-closed error for an SSE event whose `type` is outside the caller's event enum (a
 *  protocol drift). Loud, never silently ignored (AGENTS.md non-negotiable). */
export function unknownEvent(type: string): CliError {
  return new CliError({
    code: "SSE_PROTOCOL_VIOLATION",
    exit: EXIT.RUNTIME_UNAVAILABLE,
    message: `unknown SSE event type ${JSON.stringify(type)} — not in the OperationEvent contract vocabulary`,
  });
}
