import { Request, Response, RequestHandler } from 'express';
import { MapIndex } from './common.js';

/**
 * Plugin definition for extending the routing lifecycle.
 *
 * A plugin can:
 * - wrap route handlers (via `wrap`)
 * - hook into the request lifecycle (`onRequest`, `onResponse`, `onError`)
 *
 * Execution model:
 * - `wrap` transforms the final handler (composition phase)
 * - `onRequest` runs before middleware/handler (can control flow via `next`)
 * - `onResponse` runs after successful handler execution
 * - `onError` runs when an error is thrown in the pipeline
 *
 * Notes:
 * - All hooks support async execution
 * - `onRequest` must call `next()` to continue the pipeline
 * - `wrap` should return a new RequestHandler without mutating the original
 */
type PluginContext<Config = any, State = Record<MapIndex, any>> = {
    req: Request;
    res: Response;
    config?: Config;
    state: State;
};
type Plugin<Config = any, State = Record<MapIndex, any>> = {
    name: string;
    wrap?: (handler: RequestHandler, config?: Config) => RequestHandler;
    onRequest?: (ctx: PluginContext<Config, State>, next: () => Promise<void>) => Promise<void>;
    onResponse?: (ctx: PluginContext<Config, State>) => Promise<void>;
    onError?: (err: unknown, ctx: PluginContext<Config, State>) => Promise<void>;
    validateConfig?: (config: Config) => void;
};
type CacheConfig = {
    ttl?: number;
    max?: number;
};
type CacheEntry = {
    expires: number;
    status: number;
    body: any;
};
type CircutBreakerConfig = {
    threshold: number;
    cooldown: number;
    considerError?: (err: unknown) => boolean;
};
type CircuteBreakerEntryState = {
    failures: number;
    openUntil: number;
    halfOpen: boolean;
    inFlight: boolean;
};
type TimeoutConfig = {
    ms: number;
};
type RetryConfig = {
    attempts: number;
    delay?: number;
    shouldRetry?: (err: any) => boolean;
};

export type { CacheConfig, CacheEntry, CircutBreakerConfig, CircuteBreakerEntryState, Plugin, PluginContext, RetryConfig, TimeoutConfig };
