import { Logger } from "./logger.js";
import { ChatCompletionRequest, Fixture, RecordConfig, RecordProviderKey } from "./types.js";
import * as http$1 from "node:http";

//#region src/recorder.d.ts

/**
 * Captured upstream response, exposed to the `beforeWriteResponse` hook so
 * callers can decide whether to relay it or mutate it (e.g. chaos injection).
 */
interface ProxyCapturedResponse {
  status: number;
  contentType: string;
  body: Buffer;
}
interface ProxyOptions {
  /**
   * Called after the upstream response has been captured and recorded, but
   * before the relay to the client. Contract when the hook returns `true`:
   *   1. It wrote its own response body on `res`.
   *   2. It journaled the outcome (proxyAndRecord will NOT journal it).
   *   3. proxyAndRecord skips its default relay and returns `"handled_by_hook"`.
   *
   * Returning `false` (or omitting the hook) lets proxyAndRecord relay the
   * upstream response normally and leaves journaling to the caller via the
   * `"relayed"` outcome. Rejected promises propagate and leave the response
   * unwritten.
   *
   * NOT invoked when the upstream response was streamed progressively to the
   * client (SSE, NDJSON, or binary event streams) — the bytes are already on
   * the wire and can't be mutated.
   * Callers that need to observe the bypass should pass `onHookBypassed`.
   */
  beforeWriteResponse?: (response: ProxyCapturedResponse) => boolean | Promise<boolean>;
  /**
   * Called when `beforeWriteResponse` was provided but could not be invoked
   * because the upstream response was streamed to the client progressively.
   * The hook was rolled + wired but the bytes left before it could fire.
   * Intended for observability (log/metric/journal annotation) — proxyAndRecord
   * still returns `"relayed"`.
   */
  onHookBypassed?: (reason: "sse_streamed" | "ndjson_streamed" | "binary_streamed") => void;
}
/**
 * Outcome of a proxyAndRecord call, returned so the caller can decide whether
 * to journal, fall through, or stop — without sharing a mutable flag with the
 * `beforeWriteResponse` hook.
 *
 * - `"not_configured"` — no upstream URL for this provider; caller should fall
 *    through to its next branch (typically strict/404).
 * - `"relayed"` — the default code path wrote a response (upstream success or
 *    synthesized 502 error). Caller should journal the outcome.
 * - `"handled_by_hook"` — the hook wrote + journaled its own response. Caller
 *    should not double-journal.
 */
type ProxyOutcome = "not_configured" | "relayed" | "handled_by_hook";
/**
 * Result of `persistFixture`:
 * - `"skipped"` — proxy-only mode; the caller has nothing else to do.
 * - `"written"` — fixture saved to `filepath` and (unless the match was empty)
 *    registered into the in-memory cache so the next identical request matches.
 * - `"failed"` — filesystem write failed. Caller decides how to surface it
 *    (e.g. setting `X-AIMock-Record-Error` on a relay response).
 */

/**
 * Proxy an unmatched request to the real upstream provider, record the
 * response as a fixture on disk and in memory, then relay the response
 * back to the original client.
 */
declare function proxyAndRecord(req: http$1.IncomingMessage, res: http$1.ServerResponse, request: ChatCompletionRequest, providerKey: RecordProviderKey, pathname: string, fixtures: Fixture[], defaults: {
  record?: RecordConfig;
  logger: Logger;
  requestTransform?: (req: ChatCompletionRequest) => ChatCompletionRequest;
}, rawBody?: string, options?: ProxyOptions): Promise<ProxyOutcome>;
/**
 * Decodes a sequence of byte chunks to UTF-8 text for SSE/NDJSON frame
 * splitting on the streamed-capture path. Wraps Node's StringDecoder so a
 * multibyte UTF-8 character (CJK, emoji, ...) whose bytes are split across a
 * TCP chunk boundary buffers across chunks instead of decoding to U+FFFD
 * replacement characters — decoding each chunk independently with
 * Buffer#toString() would corrupt the recorded frame text.
 */
//#endregion
export { proxyAndRecord };
//# sourceMappingURL=recorder.d.ts.map