/**
 * The single decision shared by every LLM call site (job execution, ASK
 * answer, title generation, reflection): what to put in `request.model`.
 *
 *  - Gateway (proxy) mode routes by ROLE. The AAO Gateway resolves the role
 *    (auto/fast/quality/reflection) to a least-busy backend declaring it, so
 *    a heterogeneous GPU pool stays grouped by performance tier instead of by
 *    exact model name. No /v1/models discovery, no model auto-select — those
 *    collapsed every tier onto backends[0] (the 2026-06-09 over-concentration
 *    bug).
 *  - Direct mode sends the resolved model name (piece override, configured
 *    model, or omission for llama-server) exactly as before.
 *
 * The direct-model side is a thunk so gateway mode never runs the (logging,
 * auto-select) resolution path. See
 * docs/superpowers/plans/2026-06-09-role-based-gateway-routing.md.
 */
export function llmRoutingKey(params: {
  /** True when the worker connects through the AAO Gateway (connection_type: aao_gateway → proxy). */
  isGateway: boolean;
  /** The job's required tier (or the worker's serving tier for title generation). */
  role: string | undefined;
  /** Lazily resolves the direct-mode model. NOT called in gateway mode. */
  resolveDirectModel: () => string | undefined;
  /** Role key when `role` is undefined. Defaults to 'auto'. */
  roleFallback?: string;
}): string | undefined {
  if (params.isGateway) {
    return params.role ?? params.roleFallback ?? 'auto';
  }
  return params.resolveDirectModel();
}

/**
 * Should the worker requeue a job because the piece pins a model this worker
 * cannot serve?
 *
 * Direct mode: requeue when the piece names a concrete model that is neither
 * in the probed `availableModels` set nor the worker's own configured model
 * — another worker may serve it.
 *
 * Gateway mode: ALWAYS false. The worker routes by role and `availableModels`
 * holds the gateway's advertised role set (not model names), so a piece that
 * pins a real model would never match and the job would requeue forever. The
 * gateway owns model selection there. See
 * docs/superpowers/plans/2026-06-09-role-based-gateway-routing.md.
 */
export function shouldRequeueForModelMismatch(params: {
  isGateway: boolean;
  pieceModel: string | undefined;
  availableModels: Set<string>;
  workerModel: string | undefined;
}): boolean {
  if (params.isGateway) return false;
  return (
    !!params.pieceModel &&
    params.availableModels.size > 0 &&
    !params.availableModels.has(params.pieceModel) &&
    params.workerModel !== params.pieceModel
  );
}
