import type { AnyMessage, Message, MessageType, MethodIdempotency, MethodInfo, PartialMessage, ServiceType } from "@bufbuild/protobuf";
import { MethodKind } from "@bufbuild/protobuf";
import type { ContextValues } from "./context-values.js";
/**
 * ServiceImpl is the interface of the implementation of a service.
 */
export type ServiceImpl<T extends ServiceType> = {
    [P in keyof T["methods"]]: MethodImpl<T["methods"][P]>;
};
/**
 * MethodImpl is the signature of the implementation of an RPC.
 */
export type MethodImpl<M extends MI> = M extends MI<infer I, infer O, MethodKind.Unary> ? UnaryImpl<I, O> : M extends MI<infer I, infer O, MethodKind.ServerStreaming> ? ServerStreamingImpl<I, O> : M extends MI<infer I, infer O, MethodKind.ClientStreaming> ? ClientStreamingImpl<I, O> : M extends MI<infer I, infer O, MethodKind.BiDiStreaming> ? BiDiStreamingImpl<I, O> : never;
interface MI<I extends Message<I> = AnyMessage, O extends Message<O> = AnyMessage, K extends MethodKind = MethodKind> {
    readonly kind: K;
    readonly name: string;
    readonly I: MessageType<I>;
    readonly O: MessageType<O>;
    readonly idempotency?: MethodIdempotency;
}
/**
 * Context for an RPC on the server. Every RPC implementation can accept a
 * HandlerContext as an argument to gain access to headers and service metadata.
 */
export interface HandlerContext {
    /**
     * Metadata for the method being called.
     */
    readonly method: MethodInfo;
    /**
     * Metadata for the service being called.
     */
    readonly service: ServiceType;
    /**
     * An AbortSignal that is aborted when the connection with the client is closed
     * or when the deadline is reached.
     *
     * The signal can be used to automatically cancel downstream calls.
     */
    readonly signal: AbortSignal;
    /**
     * If the current request has a timeout, this function returns the remaining
     * time.
     */
    readonly timeoutMs: () => number | undefined;
    /**
     * HTTP method of incoming request, usually "POST", but "GET" in the case of
     * Connect Get.
     */
    readonly requestMethod: string;
    /**
     * Incoming request headers.
     */
    readonly requestHeader: Headers;
    /**
     * Outgoing response headers.
     *
     * For methods that return a stream, response headers must be set before
     * yielding the first response message.
     */
    readonly responseHeader: Headers;
    /**
     * Outgoing response trailers.
     */
    readonly responseTrailer: Headers;
    /**
     * Name of the RPC protocol in use; one of "connect", "grpc" or "grpc-web".
     */
    readonly protocolName: string;
    /**
     * Per RPC context values that can be used to pass data to handlers.
     */
    readonly values: ContextValues;
    /**
     * The URL received by the server.
     */
    readonly url: string;
}
/**
 * Options for creating a HandlerContext.
 */
interface HandlerContextInit {
    service: ServiceType;
    method: MethodInfo;
    protocolName: string;
    requestMethod: string;
    url: string;
    timeoutMs?: number;
    shutdownSignal?: AbortSignal;
    requestSignal?: AbortSignal;
    requestHeader?: HeadersInit;
    responseHeader?: HeadersInit;
    responseTrailer?: HeadersInit;
    contextValues?: ContextValues;
}
interface HandlerContextController extends HandlerContext {
    abort(reason?: unknown): void;
}
/**
 * Create a new HandlerContext.
 *
 * The context is usually automatically created by handlers, but if a service
 * implementation is used in unit tests, this function can be used to create
 * a context.
 */
export declare function createHandlerContext(init: HandlerContextInit): HandlerContextController;
/**
 * UnaryImp is the signature of the implementation of a unary RPC.
 */
export type UnaryImpl<I extends Message<I>, O extends Message<O>> = (request: I, context: HandlerContext) => Promise<O | PartialMessage<O>> | O | PartialMessage<O>;
/**
 * ClientStreamingImpl is the signature of the implementation of a
 * client-streaming RPC.
 */
export type ClientStreamingImpl<I extends Message<I>, O extends Message<O>> = (requests: AsyncIterable<I>, context: HandlerContext) => Promise<O | PartialMessage<O>>;
/**
 * ServerStreamingImpl is the signature of the implementation of a
 * server-streaming RPC.
 */
export type ServerStreamingImpl<I extends Message<I>, O extends Message<O>> = (request: I, context: HandlerContext) => AsyncIterable<O | PartialMessage<O>>;
/**
 * BiDiStreamingImpl is the signature of the implementation of a bi-di
 * streaming RPC.
 */
export type BiDiStreamingImpl<I extends Message<I>, O extends Message<O>> = (requests: AsyncIterable<I>, context: HandlerContext) => AsyncIterable<O | PartialMessage<O>>;
/**
 * Wraps a user-provided implementation along with service and method
 * metadata in a discriminated union type.
 */
export type MethodImplSpec<I extends Message<I> = AnyMessage, O extends Message<O> = AnyMessage> = {
    service: ServiceType;
    method: MethodInfo<I, O>;
} & ({
    kind: MethodKind.Unary;
    impl: UnaryImpl<I, O>;
} | {
    kind: MethodKind.ServerStreaming;
    impl: ServerStreamingImpl<I, O>;
} | {
    kind: MethodKind.ClientStreaming;
    impl: ClientStreamingImpl<I, O>;
} | {
    kind: MethodKind.BiDiStreaming;
    impl: BiDiStreamingImpl<I, O>;
});
/**
 * Wraps a user-provided service implementation and provides metadata.
 */
export type ServiceImplSpec = {
    service: ServiceType;
    methods: {
        [key: string]: MethodImplSpec;
    };
};
/**
 * Create an MethodImplSpec - a user-provided implementation for a method,
 * wrapped in a discriminated union type along with service and method metadata.
 */
export declare function createMethodImplSpec<M extends MethodInfo>(service: ServiceType, method: M, impl: MethodImpl<M>): MethodImplSpec;
/**
 * Create an ServiceImplSpec - a user-provided service implementation wrapped
 * with metadata.
 */
export declare function createServiceImplSpec<T extends ServiceType>(service: T, impl: Partial<ServiceImpl<T>>): ServiceImplSpec;
export {};
