import type { BuildResolver, BuildResolverOptions, DisposableResolver } from 'awilix';
import type { FunctionReturning } from 'awilix/lib/container';
import type { DependencyInjectionOptions } from './DIContext.js';
/**
 * Type-level representation of a class value that infers the instance type
 * from the `prototype` property rather than from the constructor signature.
 *
 * This breaks circular type dependencies that occur when a class constructor
 * references a type derived from the module's own resolver return type
 * (e.g. `InferModuleDependencies`), because TypeScript can resolve the
 * instance type (prototype) without evaluating constructor parameter types.
 *
 * Constructor parameter types are still fully checked — the cycle is only
 * broken at the resolver inference level.
 */
type ClassValue<T> = {
    prototype: T;
};
declare module 'awilix' {
    interface ResolverOptions<T> {
        public?: boolean;
        isSSEController?: boolean;
        isDualModeController?: boolean;
    }
}
export type PublicResolver<T> = BuildResolver<T> & DisposableResolver<T> & {
    readonly __publicResolver: true;
};
export interface EnqueuedJobQueueManager {
    start(enabled?: string[] | boolean): Promise<void>;
}
export declare function asSingletonClass<T = object>(Type: ClassValue<T>, opts: BuildResolverOptions<T> & {
    public: true;
}): PublicResolver<T>;
export declare function asSingletonClass<T = object>(Type: ClassValue<T>, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
/**
 * Register a class with an additional config parameter passed to the constructor.
 * Uses asFunction wrapper internally to pass the config as a second parameter.
 * Requires PROXY injection mode.
 *
 * @example
 * ```typescript
 * myService: asClassWithConfig(MyService, { enableFeature: true }),
 * ```
 */
export declare function asClassWithConfig<T = object, Config = unknown>(Type: ClassValue<T>, config: Config, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
export declare function asSingletonFunction<T>(fn: FunctionReturning<T>, opts: BuildResolverOptions<T> & {
    public: true;
}): PublicResolver<T>;
export declare function asSingletonFunction<T>(fn: FunctionReturning<T>, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
export declare function asServiceClass<T = object>(Type: ClassValue<T>, opts: BuildResolverOptions<T> & {
    public: false;
}): BuildResolver<T> & DisposableResolver<T>;
export declare function asServiceClass<T = object>(Type: ClassValue<T>, opts?: BuildResolverOptions<T>): PublicResolver<T>;
export declare function asUseCaseClass<T = object>(Type: ClassValue<T>, opts: BuildResolverOptions<T> & {
    public: false;
}): BuildResolver<T> & DisposableResolver<T>;
export declare function asUseCaseClass<T = object>(Type: ClassValue<T>, opts?: BuildResolverOptions<T>): PublicResolver<T>;
export declare function asRepositoryClass<T = object>(Type: ClassValue<T>, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
export declare function asControllerClass<T = object>(Type: ClassValue<T>, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
export type SSEControllerModuleOptions = {
    diOptions: DependencyInjectionOptions;
    /** Enable rooms. Resolves `sseRoomBroadcaster` from DI cradle. */
    rooms?: boolean;
};
/**
 * Register an SSE controller class with the DI container.
 *
 * SSE controllers handle Server-Sent Events connections and require
 * graceful shutdown to close all active connections.
 *
 * When `diOptions.isTestMode` is true, connection spying is enabled
 * allowing tests to await connections via `controller.connectionSpy`.
 *
 * @example
 * ```typescript
 * // Without test mode
 * notificationsSSEController: asSSEControllerClass(NotificationsSSEController),
 *
 * // With test mode (enables connection spy)
 * notificationsSSEController: asSSEControllerClass(NotificationsSSEController, { diOptions }),
 *
 * // With rooms enabled (resolves sseRoomBroadcaster from DI)
 * dashboardController: asSSEControllerClass(DashboardSSEController, { diOptions, rooms: true }),
 * ```
 */
export declare function asSSEControllerClass<T = object>(Type: ClassValue<T>, sseOptions?: SSEControllerModuleOptions, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
export type DualModeControllerModuleOptions = {
    diOptions: DependencyInjectionOptions;
    /** Enable rooms. Resolves `sseRoomBroadcaster` from DI cradle. */
    rooms?: boolean;
};
/**
 * Register a dual-mode controller class with the DI container.
 *
 * Dual-mode controllers handle both SSE streaming and JSON responses on the
 * same route path, automatically branching based on the `Accept` header.
 * They require graceful shutdown to close all active SSE connections.
 *
 * When `diOptions.isTestMode` is true, connection spying is enabled
 * allowing tests to await connections via `controller.connectionSpy`.
 *
 * @example
 * ```typescript
 * // Without test mode
 * chatController: asDualModeControllerClass(ChatController),
 *
 * // With test mode (enables connection spy)
 * chatController: asDualModeControllerClass(ChatController, { diOptions }),
 *
 * // With rooms enabled (resolves sseRoomBroadcaster from DI)
 * dashboardController: asDualModeControllerClass(DashboardController, { diOptions, rooms: true }),
 * ```
 */
export declare function asDualModeControllerClass<T = object>(Type: ClassValue<T>, dualModeOptions?: DualModeControllerModuleOptions, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
export type MessageQueueConsumerModuleOptions = {
    queueName: string;
    diOptions: DependencyInjectionOptions;
};
export declare function asMessageQueueHandlerClass<T = object>(Type: ClassValue<T>, mqOptions: MessageQueueConsumerModuleOptions, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
export type EnqueuedJobWorkerModuleOptions = {
    queueName: string;
    diOptions: DependencyInjectionOptions;
};
export declare function asEnqueuedJobWorkerClass<T = object>(Type: ClassValue<T>, workerOptions: EnqueuedJobWorkerModuleOptions, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
/**
 * Helper function to register a pg-boss job processor class with the DI container.
 * Handles asyncInit/asyncDispose lifecycle and enabled check based on diOptions.
 *
 * @example
 * ```typescript
 * enrichUserPresenceJob: asPgBossProcessorClass(EnrichUserPresenceJob, {
 *   diOptions,
 *   queueName: EnrichUserPresenceJob.QUEUE_ID,
 * }),
 * ```
 */
export declare function asPgBossProcessorClass<T extends {
    start(): Promise<void>;
    stop(): Promise<void>;
}>(Type: ClassValue<T>, processorOptions: EnqueuedJobWorkerModuleOptions, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
export type PeriodicJobOptions = {
    jobName: string;
    diOptions: DependencyInjectionOptions;
};
export declare function asPeriodicJobClass<T = object>(Type: ClassValue<T>, workerOptions: PeriodicJobOptions, opts?: BuildResolverOptions<T>): BuildResolver<T> & DisposableResolver<T>;
export type JobQueueModuleOptions = {
    queueName?: string;
    diOptions: DependencyInjectionOptions;
};
export declare function asJobQueueClass<T = object>(Type: ClassValue<T>, queueOptions: JobQueueModuleOptions, opts: BuildResolverOptions<T> & {
    public: false;
}): BuildResolver<T> & DisposableResolver<T>;
export declare function asJobQueueClass<T = object>(Type: ClassValue<T>, queueOptions: JobQueueModuleOptions, opts?: BuildResolverOptions<T>): PublicResolver<T>;
export declare function asEnqueuedJobQueueManagerFunction<T extends EnqueuedJobQueueManager>(fn: FunctionReturning<T>, diOptions: DependencyInjectionOptions, opts: BuildResolverOptions<T> & {
    public: false;
}): BuildResolver<T> & DisposableResolver<T>;
export declare function asEnqueuedJobQueueManagerFunction<T extends EnqueuedJobQueueManager>(fn: FunctionReturning<T>, diOptions: DependencyInjectionOptions, opts?: BuildResolverOptions<T>): PublicResolver<T>;
export {};
