import type { HttpContractConfig } from "../contracts/index.js";
import type { AnyPorts, BoundGate, GatePort, PolicyDefinition } from "../ports/index.js";
import type { TraceContext } from "../tracing/index.js";
import type { HttpRequestLike, MaybePromise } from "./http.js";
import type { TrustedRequestInfo } from "./trusted-proxy.js";
/**
 * Arguments passed to the `context.request` factory after a route is matched.
 */
export type RequestContextArgs<Ports extends AnyPorts = AnyPorts> = {
    /**
     * Framework-neutral request.
     */
    req: HttpRequestLike;
    /**
     * Request metadata resolved from the server's explicit trusted-proxy policy.
     * Forwarding headers never affect this value unless
     * `createServer({ trustedProxy })` opts into them.
     */
    requestInfo: TrustedRequestInfo;
    /**
     * Final app ports, including ports contributed by providers.
     */
    ports: Ports;
    /**
     * Matched contract, when the request resolved to a registered route.
     */
    contract?: HttpContractConfig;
    /**
     * Request correlation ID resolved by the server from the configured request
     * ID header, or generated when the request did not send one.
     */
    requestId: string;
    /**
     * W3C trace context resolved by the server from the incoming `traceparent`
     * header, or generated when the request did not send one. Spread this into
     * the context (`...trace`) to correlate downstream activity.
     */
    trace: TraceContext;
};
/**
 * Arguments passed to the `context.service` factory.
 */
export type ServiceContextArgs<Ports extends AnyPorts = AnyPorts, ServiceInput = void> = {
    /**
     * Final app ports, including ports contributed by providers.
     */
    ports: Ports;
    /**
     * Caller-provided input such as the service actor or tenant.
     */
    input: ServiceInput;
    /**
     * Fresh correlation ID generated for this service context.
     */
    requestId: string;
    /**
     * Fresh W3C trace context generated for this service context. Spread this
     * into the context (`...trace`) to correlate downstream activity.
     */
    trace: TraceContext;
};
/**
 * App context without its `gate` property.
 *
 * Context factories return seeds; the server attaches the gate declared by
 * the blueprint's `gate` selector, so hand-binding `gate` in a factory is a
 * type error.
 */
export type ContextSeed<Ctx> = Omit<Ctx, "gate"> & {
    gate?: never;
};
type ContextGateOption<Ctx, Ports extends AnyPorts> = [Ctx] extends [
    {
        gate: BoundGate<infer TPolicies extends readonly PolicyDefinition[]>;
    }
] ? {
    /**
     * Select the gate port the server attaches to every context it builds.
     */
    gate: (ports: Ports) => GatePort<ContextSeed<Ctx>, TPolicies>;
} : {
    /**
     * Gate selection is only available when the context type declares a
     * `gate` property.
     */
    gate?: never;
};
/**
 * Context blueprint accepted by `createServer(...)`.
 *
 * The server owns context assembly: `request` and `service` return context
 * seeds, and the server attaches the gate declared by `gate` so identity
 * changes can never authorize against a stale context.
 */
export type ServerContextOptions<Ctx, Ports extends AnyPorts = AnyPorts, ServiceInput = void> = {
    /**
     * Build the per-request context seed.
     */
    request: (args: RequestContextArgs<Ports>) => MaybePromise<ContextSeed<Ctx>>;
    /**
     * Build a service context seed for schedules, outbox drains, tasks, and
     * background work. Required before `server.createServiceContext(...)` can
     * be called.
     */
    service?: (args: ServiceContextArgs<Ports, ServiceInput>) => MaybePromise<ContextSeed<Ctx>>;
} & ContextGateOption<Ctx, Ports>;
/**
 * Context configuration accepted by `createServer(...)`.
 *
 * Contexts without a `gate` property may use the plain request-factory
 * shorthand. Contexts with a `gate` must use the blueprint form so the server
 * owns gate attachment.
 */
export type ServerContextConfig<Ctx, Ports extends AnyPorts = AnyPorts, ServiceInput = void> = [Ctx] extends [{
    gate: unknown;
}] ? ServerContextOptions<Ctx, Ports, ServiceInput> : ((args: RequestContextArgs<Ports>) => MaybePromise<Ctx>) | ServerContextOptions<Ctx, Ports, ServiceInput>;
/**
 * Argument tuple for `createServiceContext(...)`.
 *
 * Servers without a declared service input are callable with no arguments;
 * optional inputs stay optional at the call site.
 */
export type ServiceContextInputArgs<ServiceInput> = [ServiceInput] extends [
    void
] ? [] : undefined extends ServiceInput ? [input?: ServiceInput] : [input: ServiceInput];
type AnyGateSelector<Ports extends AnyPorts> = (ports: Ports) => Pick<GatePort<unknown>, "attach">;
/**
 * Normalized runtime view of a server context configuration.
 */
export type ResolvedServerContext<Ctx, Ports extends AnyPorts, ServiceInput> = {
    request: (args: RequestContextArgs<Ports>) => MaybePromise<ContextSeed<Ctx> | Ctx>;
    service?: (args: ServiceContextArgs<Ports, ServiceInput>) => MaybePromise<ContextSeed<Ctx>>;
    gate?: AnyGateSelector<Ports>;
};
/**
 * Normalize a server context configuration into its runtime parts.
 */
export declare function resolveServerContext<Ctx, Ports extends AnyPorts, ServiceInput>(config: ServerContextConfig<Ctx, Ports, ServiceInput>): ResolvedServerContext<Ctx, Ports, ServiceInput>;
/**
 * Create the context finalizer for a resolved server context.
 *
 * When the blueprint declares a gate, the finalizer strips hand-assigned
 * `gate` values from seeds and attaches the live gate. Without a gate
 * declaration the seed is the context.
 */
export declare function createContextFinalizer<Ctx, Ports extends AnyPorts, ServiceInput>(resolved: ResolvedServerContext<Ctx, Ports, ServiceInput>, getPorts: () => Ports): (seed: ContextSeed<Ctx> | Ctx) => Ctx;
export {};
//# sourceMappingURL=context.d.ts.map