import { ChatCompletionRequest, ContentPart, Fixture } from "./types.js";

//#region src/router.d.ts

/**
 * Extract the text content from a message's content field.
 * Handles both plain string content and array-of-parts content
 * (e.g. `[{type: "text", text: "..."}]` as sent by some SDKs).
 *
 * Multi-part text is joined with `""` (the parts form one logical body split
 * across segments). Empty handling is symmetric with the string path: a string
 * `""` returns `""`, and an array containing at least one text part whose
 * combined text is empty likewise returns `""` (NOT `null`). `null` is reserved
 * for "no text content at all" — null content, or an array with no text parts —
 * so callers can distinguish "absent" from "present but empty" the same way for
 * both content shapes.
 */
declare function getTextContent(content: string | ContentPart[] | null): string | null;
/**
 * Result of {@link matchFixtureDiagnostic}: the matched fixture (or `null`) plus
 * the number of fixtures that matched the request SHAPE (every predicate above
 * the sequenceIndex/turnIndex gates) but were rejected ONLY by the
 * sequenceIndex/turnIndex count state.
 *
 * `skippedBySequenceOrTurn > 0` with `fixture === null` distinguishes a
 * "sequence/turn exhausted" miss (candidate fixtures existed but their count
 * gate had moved on) from a true "no fixture had a matching shape" miss — used
 * to disambiguate the strict-mode 503 message.
 */
interface MatchFixtureDiagnostic {
  fixture: Fixture | null;
  skippedBySequenceOrTurn: number;
  /**
   * `true` when the served fixture was selected by relaxed content-anchored
   * matching even though its `turnIndex` is defined and does NOT equal the
   * request's assistant-message count — i.e. the legacy strict turnIndex gate
   * (now opt-in via `AIMOCK_STRICT_TURN_INDEX`) WOULD HAVE rejected it. Absent /
   * falsy on canonical-position matches, non-turnIndexed matches, and misses.
   * Additive optional field — existing handler destructures are unaffected.
   */
  turnIndexRelaxed?: boolean;
  /**
   * How the served fixture was selected: `"turnIndex"` when its `turnIndex`
   * sits exactly at the current assistant count (canonical position),
   * `"content"` otherwise (a non-turnIndexed match or a relaxed off-by-N
   * match). Absent on misses. Additive optional field.
   */
  matchedBy?: "content" | "turnIndex";
}
/**
 * Optional matcher tuning.
 *
 * `strictTurnIndex` restores the legacy behaviour where `turnIndex` must equal
 * the request's assistant-message count exactly (a hard reject gate). It is set
 * by the record path, where a miss proxies upstream to capture a fresh turn; an
 * earlier-turn fixture must not shadow a longer request or the new turn would
 * never be recorded. Replay (the default, `false`) treats `turnIndex` as a
 * non-fatal disambiguator instead — see {@link selectByTurnIndex}.
 */
interface MatchOptions {
  strictTurnIndex?: boolean;
  /**
   * Optional sink for the one-shot relaxed-turnIndex divergence warning. Handlers
   * pass their `defaults.logger`; the structural `{ warn }` shape avoids an
   * import cycle with logger.ts and keeps the matcher decoupled. When omitted no
   * warning is emitted (the diagnostic fields are still populated). The Logger's
   * own level gate keeps a passing programmatic run (silent default) quiet.
   */
  logger?: {
    warn(...args: unknown[]): void;
  };
}
/**
 * Test-only hook to clear the throttle state between cases. Not part of the
 * public contract. `WeakSet` has no `.clear()`, so reassign a fresh instance.
 */

/**
 * Match a fixture against a request, additionally reporting WHY a `null` result
 * occurred. Shares the exact predicate loop with {@link matchFixture}; a fixture
 * that passes every shape predicate but fails ONLY the sequenceIndex or
 * turnIndex gate increments `skippedBySequenceOrTurn`. {@link matchFixture} is a
 * thin wrapper that returns the `.fixture` field, so existing callers are
 * unaffected.
 */
declare function matchFixtureDiagnostic(fixtures: Fixture[], req: ChatCompletionRequest, matchCounts?: Map<Fixture, number>, requestTransform?: (req: ChatCompletionRequest) => ChatCompletionRequest, options?: MatchOptions): MatchFixtureDiagnostic;
/**
 * Match a fixture against a request, returning the fixture or `null`. Thin
 * wrapper over {@link matchFixtureDiagnostic} that discards the skip diagnostic
 * — preserves the historical signature for all existing callers.
 */
declare function matchFixture(fixtures: Fixture[], req: ChatCompletionRequest, matchCounts?: Map<Fixture, number>, requestTransform?: (req: ChatCompletionRequest) => ChatCompletionRequest, options?: MatchOptions): Fixture | null;
//# sourceMappingURL=router.d.ts.map
//#endregion
export { MatchFixtureDiagnostic, getTextContent, matchFixture, matchFixtureDiagnostic };
//# sourceMappingURL=router.d.ts.map