import { contextSymbol, UniversalFn, UniversalHandler, UniversalMiddleware, Get, UniversalRouter, UniversalRouterInterface, EnhancedMiddleware } from '@universal-middleware/core';
import { RouteHandlerMethod, FastifyPluginAsync, FastifyRequest, FastifyInstance } from 'fastify';

declare const pendingMiddlewaresSymbol: unique symbol;
declare const wrappedResponseSymbol: unique symbol;
type FastifyHandler<In extends Universal.Context> = UniversalFn<UniversalHandler<In>, RouteHandlerMethod>;
type FastifyMiddleware<In extends Universal.Context, Out extends Universal.Context> = UniversalFn<UniversalMiddleware<In, Out>, FastifyPluginAsync>;
declare module "fastify" {
    interface FastifyRequest {
        [pendingMiddlewaresSymbol]?: ((response: Response) => Response | Promise<Response | undefined> | undefined | Promise<undefined>)[];
        [wrappedResponseSymbol]?: boolean;
    }
    interface FastifyContextConfig {
        [contextSymbol]: unknown;
    }
}
declare function createHandler<T extends unknown[], InContext extends Universal.Context>(handlerFactory: Get<T, UniversalHandler<InContext>>): Get<T, FastifyHandler<InContext>>;
declare function createMiddleware<T extends unknown[], InContext extends Universal.Context, OutContext extends Universal.Context>(middlewareFactory: Get<T, UniversalMiddleware<InContext, OutContext>>): Get<T, FastifyMiddleware<InContext, OutContext>>;
declare function getContext<InContext extends Universal.Context = Universal.Context>(req: FastifyRequest): InContext;

type App = FastifyInstance;
type EnhancedMiddlewareFastify = EnhancedMiddleware | EnhancedMiddleware<Universal.Context, Universal.Context, "fastify">;
declare class UniversalFastifyRouter extends UniversalRouter implements UniversalRouterInterface<"async"> {
    #private;
    constructor(app: App);
    use(middleware: EnhancedMiddlewareFastify): Promise<this>;
    applyCatchAll(): Promise<this>;
}
declare function apply(app: App, middlewares: EnhancedMiddlewareFastify[]): Promise<void>;

export { type App, type FastifyHandler, type FastifyMiddleware, UniversalFastifyRouter, apply, createHandler, createMiddleware, getContext };
