import type { AnyPorts } from "../ports/index.js";
import type { ServerContextConfig } from "./context.js";

/**
 * Declare a server context blueprint once and share it between the runtime
 * server and tests.
 *
 * The helper preserves the blueprint exactly as written — `request`,
 * `service`, and `gate` keep their inferred types — so apps can keep the
 * blueprint in a canonical `server/context.ts` file and pass the same value to
 * `createServer(...)` (through an adapter such as `createNextServer` or
 * `createFetchServer`) and to `createTestApp(...)`.
 *
 * @example
 * ```ts
 * // server/context.ts
 * export const appContext = defineServerContext<AppContext, AppPorts>()({
 *   gate: (ports) => ports.gate,
 *   request: async ({ req, ports, requestId, requestInfo, trace }) => ({
 *     actor: await resolveActor(req),
 *     auth: null,
 *     requestId,
 *     requestInfo,
 *     ...trace,
 *     ports,
 *   }),
 *   service: ({ ports, requestId, trace }) => ({
 *     actor: createServiceActor("app-service"),
 *     auth: null,
 *     requestId,
 *     ...trace,
 *     ports,
 *   }),
 * });
 * ```
 *
 * @returns A function that collects and returns the typed context blueprint.
 */
export function defineServerContext<Ctx, Ports extends AnyPorts = AnyPorts>(): <
  ServiceInput = void,
>(
  blueprint: ServerContextConfig<Ctx, Ports, ServiceInput>,
) => ServerContextConfig<Ctx, Ports, ServiceInput> {
  return (blueprint) => blueprint;
}
