import * as http from 'node:http';
import { Readable } from 'node:stream';

declare enum LogLevel {
    COMPLETE_SILENCE = 0,// Nothing - not even fatals
    QUIET = 100,// Log nothing except fatals, errors and warnings
    INFO = 200,// Log info messages
    START_UP = 250,// Log start up (and shutdown) as well as info messages
    DEBUG = 300,// Log debug messages
    TRACE = 400
}
declare class Logger {
    private _name;
    private _timestamp;
    private _timestampLocale;
    private _timestampTz;
    private _logLevel;
    /**
     * Generates a timestamp string to prefix log messages.
     * Returns an empty string if timestamps are disabled. Otherwise returns
     * the formatted timestamp string.
     */
    private timestamp;
    private convertLevel;
    constructor(name: string);
    fatal(...args: any): void;
    error(...args: any): void;
    warn(...args: any): void;
    info(...args: any): void;
    startupMsg(...args: any): void;
    shutdownMsg(...args: any): void;
    debug(...args: any): void;
    trace(...args: any): void;
    force(...args: any): void;
    setLevel(level: LogLevel): void;
}

/**
 * Config manager module. Provides functions to retrieve config values from various sources like
 * CLI, environment variables, and env file. Includes utility functions to handle config value
 * lookup, type conversion, error handling etc.
 */
/**
 * Type defines the options for retrieving a configuration value.
 *
 * @param cmdLineFlag - An optional command line flag.
 * @param silent - An optional flag to silence logging the retrieval.
 * @param redact - An optional flag to redact the value in logs.
 */
type ConfigOptions = {
    cmdLineFlag?: string;
    silent?: boolean;
    redact?: boolean;
};
/**
 * Represents an error that occurred while retrieving a config value
 */
declare class ConfigError {
    message: string;
    constructor(message: string);
}

type ReqRes = {
    statusCode: number;
    headers: Headers;
    body: any;
    responseTime: number;
    response?: Response;
};
type ReqOptions = {
    method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS";
    searchParams?: Record<string, string>;
    headers?: Record<string, string>;
    body?: object | [] | string;
    auth?: {
        username: string;
        password: string;
    };
    bearerToken?: string;
    timeout?: number;
    handleResponse?: boolean;
    keepalive?: boolean;
    cache?: RequestCache;
    credentials?: RequestCredentials;
    mode?: RequestMode;
    redirect?: RequestRedirect;
    referrer?: string;
    referrerPolicy?: ReferrerPolicy;
    signal?: AbortSignal;
};
declare class ReqAborted {
    timedOut: boolean;
    message: string;
    constructor(timedOut: boolean, message: string);
}
declare class ReqError {
    status: number;
    message: string;
    constructor(status: number, message: string);
}

type SseServerOptions = {
    retryInterval?: number;
    pingInterval?: number;
    pingEventName?: string;
};
declare class SseServer {
    private _res;
    private _lastEventId?;
    private _pingSeqNum;
    constructor(req: http.IncomingMessage, res: http.ServerResponse, opts: SseServerOptions);
    get lastEventId(): string | undefined;
    setRetry(delay: number): void;
    sendData(data: object | unknown[] | string | number, options: {
        event?: string;
        id?: number;
    }): void;
    close(): void;
}

type Cookie = {
    name: string;
    value: string;
    maxAge?: number;
    path?: string;
    secure?: boolean;
    httpOnly?: boolean;
    sameSite?: "Strict" | "Lax" | "None";
    domain?: string;
};
declare class HttpError {
    status: number;
    message: string;
    constructor(status: number, message?: string);
}
type HttpRedirectStatusCode = 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308;
declare class HttpRedirect {
    statusCode: HttpRedirectStatusCode;
    location: string;
    message: string;
    constructor(statusCode: HttpRedirectStatusCode | undefined, location: string, message?: string);
}
type ServerTimingMetric = {
    name: string;
    duration?: number;
    description?: string;
};
type ServerRequest = http.IncomingMessage & {
    validUrl: boolean;
    urlObj: URL;
    params: Record<string, any>;
    sseServer?: SseServer;
    json?: any;
    body?: Buffer;
    matchedInfo: any;
    handled: boolean;
    compressResponse: boolean;
    checkApiRoutes: boolean;
    checkSsrRoutes: boolean;
    checkStaticFiles: boolean;
    handle404: boolean;
    getCookie(cookieName: string): string | null;
    setServerTimingHeader(value: string): void;
};
declare const enhanceIncomingMessage: (req: http.IncomingMessage) => ServerRequest;
type ServerResponse = http.ServerResponse & {
    receiveTime: number;
    redirected: boolean;
    latencyMetricName: string;
    serverTimingsMetrics: (ServerTimingMetric | string)[];
    body?: string | Buffer;
    json?: object | [] | string | number | boolean;
    streamRes?: {
        body: Readable;
        fileName?: string;
    };
    enhancedReq: ServerRequest;
    setCookies(cookies: Cookie[]): void;
    clearCookies(cookies: string[], domain?: string): void;
    setServerTimingHeader(): void;
    redirect(location: string, statusCode?: HttpRedirectStatusCode, message?: string): void;
    addServerTimingMetric(name: string, duration?: number, description?: string): void;
    addServerTimingHeader(header: string): void;
};
declare const enhanceServerResponse: (res: http.ServerResponse) => ServerResponse;

type Middleware = (req: ServerRequest, res: ServerResponse, next: () => Promise<void>) => Promise<void>;
type ExpressMiddleware = (req: http.IncomingMessage, res: http.ServerResponse, next: (e?: any) => void) => void;
type MiddlewareMethods = "GET" | "PUT" | "POST" | "DELETE" | "PATCH";
type CorsOptions = {
    originsAllowed?: "*" | string[];
    methodsAllowed?: "*" | MiddlewareMethods[];
    headersAllowed?: "*" | string[];
    headersExposed?: "*" | string[];
    credentialsAllowed?: boolean;
    maxAge?: number;
};
type CsrfChecksOptions = {
    methods?: MiddlewareMethods[];
    checkType?: "custom-req-header" | "naive-double-submit-cookie" | "signed-double-submit-cookie";
    header?: string;
    cookie?: string;
    secret?: string;
    hashAlgo?: string;
    signatureSeparator?: string;
};
type SecurityHeadersOptions = {
    headers?: {
        name: string;
        value: string;
    }[];
    useDefaultHeaders?: boolean;
};

type RouterMatch = {
    params: Record<string, string>;
    matchedInfo: any;
};
type RouterMatchFunc = (url: URL) => RouterMatch | false;
type EndpointOptions = {
    generateMatcher?: (path: string) => RouterMatchFunc;
    useDefaultMiddlewares?: boolean;
    middlewareList?: Middleware[];
    sseServerOptions?: SseServerOptions;
    etag?: boolean;
};
type EndpointCallback = (req: ServerRequest, res: ServerResponse) => Promise<void> | void;
type Method = "ALL" | "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS" | "HEAD";
type Route = {
    get: (callback: EndpointCallback, endpointOptions?: EndpointOptions) => Route;
    patch: (callback: EndpointCallback, endpointOptions?: EndpointOptions) => Route;
    post: (callback: EndpointCallback, endpointOptions?: EndpointOptions) => Route;
    put: (callback: EndpointCallback, endpointOptions?: EndpointOptions) => Route;
    del: (callback: EndpointCallback, endpointOptions?: EndpointOptions) => Route;
    all: (callback: EndpointCallback, endpointOptions?: EndpointOptions) => Route;
};
type RouterConfig = {
    minCompressionSize?: number;
    defaultCharSet?: string;
};
declare class Router {
    private _basePathDelimited;
    private _basePath;
    private _minCompressionSize;
    private _defaultCharSet;
    private _logger;
    private _methodListMap;
    private _defaultMiddlewareList;
    constructor(basePath: string, config?: RouterConfig);
    get basePath(): string;
    private searchMethodElements;
    private findEndpoint;
    private callMiddleware;
    private callEndpoint;
    private hasNoBody;
    private bodyNotModified;
    private lookupType;
    private streamRes;
    private addResponseBody;
    inPath(pathname: string): boolean;
    handleReq(req: ServerRequest, res: ServerResponse): Promise<void>;
    pathToRegexMatcher(path: string): RouterMatchFunc;
    matchAllMatcher(_: string): RouterMatchFunc;
    use(middleware: Middleware): Router;
    endpoint(method: Method, path: string, callback: EndpointCallback, endpointOptions?: EndpointOptions): Router;
    del(path: string, callback: EndpointCallback, endpointOptions?: EndpointOptions): Router;
    get(path: string, callback: EndpointCallback, endpointOptions?: EndpointOptions): Router;
    patch(path: string, callback: EndpointCallback, endpointOptions?: EndpointOptions): Router;
    post(path: string, callback: EndpointCallback, endpointOptions?: EndpointOptions): Router;
    put(path: string, callback: EndpointCallback, endpointOptions?: EndpointOptions): Router;
    all(path: string, callback: EndpointCallback, endpointOptions?: EndpointOptions): Router;
    route(path: string): Route;
    static body(options?: {
        maxBodySize?: number;
    }): Middleware;
    static json(): Middleware;
    static cors(options?: CorsOptions): Middleware;
    static csrf(options?: CsrfChecksOptions): Middleware;
    static getSecHeaders(options: SecurityHeadersOptions): {
        name: string;
        value: string;
    }[];
    static secHeaders(options: SecurityHeadersOptions): Middleware;
    static expressWrapper(options: ExpressMiddleware): Middleware;
    static dontCompressResponse(): Middleware;
    static setLatencyMetricName(name: string): Middleware;
}

type HealthcheckCallback = () => Promise<boolean>;
declare class HttpConfigError {
    message: string;
    constructor(message: string);
}
type HttpConfig = {
    keepAliveTimeout?: number;
    headerTimeout?: number;
    defaultRouterBasePath?: string;
    healthcheckPath?: string;
    healthcheckGoodRes?: number;
    healthcheckBadRes?: number;
    enableHttps?: boolean;
    httpsKeyFile?: string;
    httpsCertFile?: string;
    staticFileServer?: {
        path: string;
        immutableRegExp?: string[];
        securityHeaders?: {
            name: string;
            value: string;
        }[];
    };
};
declare class HttpServer {
    private _logger;
    private _socketMap;
    private _socketId;
    private _networkInterface;
    private _networkPort;
    private _networkIp;
    private _baseUrl;
    private _name;
    private _healthcheckCallbacks;
    private _httpKeepAliveTimeout;
    private _httpHeaderTimeout;
    private _healthCheckPath;
    private _healthCheckGoodResCode;
    private _healthCheckBadResCode;
    private _enableHttps;
    private _keyFile?;
    private _certFile?;
    private _apiRouterList;
    private _defaultApiRouter;
    private _ssrRouter;
    private _staticFileServer?;
    private _server?;
    constructor(networkInterface: string, networkPort: number, config?: HttpConfig);
    get networkIp(): string;
    get networkPort(): number;
    get baseUrl(): string;
    get httpsEnabled(): boolean;
    get name(): string;
    get ssrRouter(): Router;
    get server(): http.Server | null;
    get reqHandler(): (req: ServerRequest, res: ServerResponse) => Promise<void>;
    private findInterfaceIp;
    private startListening;
    private handleReq;
    private healthcheckCallback;
    start(): Promise<void>;
    stop(): Promise<void>;
    addHealthcheck(callback: HealthcheckCallback): void;
    addRouter(basePath: string, routerConfig?: RouterConfig): Router;
    router(basePath?: string): Router | undefined;
    use(middleware: Middleware): Router;
    del(path: string, callback: EndpointCallback, options?: EndpointOptions): Router;
    get(path: string, callback: EndpointCallback, options?: EndpointOptions): Router;
    patch(path: string, callback: EndpointCallback, options?: EndpointOptions): Router;
    post(path: string, callback: EndpointCallback, options?: EndpointOptions): Router;
    put(path: string, callback: EndpointCallback, options?: EndpointOptions): Router;
    endpoint(method: Method, path: string, callback: EndpointCallback, options?: EndpointOptions): Router;
    route(path: string): Route;
}

declare class BSPlugin {
    private _name;
    private _version;
    private _logger;
    constructor(name: string, version: string);
    protected stop(): Promise<void>;
    get name(): string;
    get version(): string;
    get stopHandler(): () => Promise<void>;
    protected fatal(...args: any): void;
    protected error(...args: any): void;
    protected warn(...args: any): void;
    protected info(...args: any): void;
    protected startupMsg(...args: any): void;
    protected shutdownMsg(...args: any): void;
    protected debug(...args: any): void;
    protected trace(...args: any): void;
    protected force(...args: any): void;
}

type BSQuestionOptions = {
    muteAnswer?: boolean;
    muteChar?: string;
};
declare const bs: Readonly<{
    request: (origin: string, path: string, reqOptions?: ReqOptions) => Promise<ReqRes>;
    /**
     * Gets a string config value.
     *
     * @param config - The config key to get.
     * @param defaultVal - The default value if config not found.
     * @param options - Options for getting the config.
     * @returns The string config value.
     */
    getConfigStr: (config: string, defaultVal?: string, options?: ConfigOptions) => string;
    /**
     * Gets a boolean config value.
     *
     * @param config - The config key to get.
     * @param defaultVal - The default value if config not found.
     * @param options - Options for getting the config.
     * @returns The boolean config value.
     */
    getConfigBool: (config: string, defaultVal?: boolean, options?: ConfigOptions) => boolean;
    /**
     * Gets a number config value.
     *
     * @param config - The config key to get.
     * @param defaultVal - The default value if config not found.
     * @param options - Options for getting the config.
     * @returns The number config value.
     */
    getConfigNum: (config: string, defaultVal?: number, options?: ConfigOptions) => number;
    /**
     * Gets an object config value.
     *
     * @param config - The config key to get.
     * @param defaultVal - The default value if config not found.
     * @param options - Options for getting the config.
     * @returns The object config value.
     */
    getConfigObj: (config: string, defaultVal?: Record<string, any>, options?: ConfigOptions) => Record<string, any>;
    /**
     * Gets an array config value.
     *
     * @param config - The config key to get.
     * @param defaultVal - The default value if config not found.
     * @param options - Options for getting the config.
     * @returns The object config value.
     */
    getConfigArray: (config: string, defaultVal?: any[], options?: ConfigOptions) => any[];
    fatal: (...args: any) => void;
    error: (...args: any) => void;
    warn: (...args: any) => void;
    info: (...args: any) => void;
    startupMsg: (...args: any) => void;
    shutdownMsg: (...args: any) => void;
    debug: (...args: any) => void;
    trace: (...args: any) => void;
    force: (...args: any) => void;
    setLogLevel: (level: LogLevel) => void;
    shellVersion: () => string;
    setFinallyHandler: (handler: () => Promise<void>) => void;
    setStopHandler: (handler: () => Promise<void>) => void;
    setRestartHandler: (handler: () => Promise<void>) => void;
    exit: (code: number, hard?: boolean) => Promise<void>;
    restart: () => Promise<void>;
    shutdownError: (code?: number, testing?: boolean) => Promise<void>;
    addHttpServer: (networkInterface: string, networkPort: number, httpConfig?: HttpConfig, startServer?: boolean) => Promise<HttpServer>;
    httpServer: (index?: number) => HttpServer;
    addPlugin: (name: string, pluginClass: new (name: string, options?: any) => BSPlugin, config?: any) => BSPlugin;
    plugin: (name: string) => BSPlugin;
    save: (name: string, value: any) => void;
    update: (name: string, value: any) => void;
    retrieve: (name: string) => any;
    sleep: (durationInSeconds: number) => Promise<void>;
    question: (ask: string, questionOptions?: BSQuestionOptions) => Promise<string>;
}>;

export { BSPlugin, ConfigError, HttpConfigError, HttpError, HttpRedirect, HttpServer, LogLevel, Logger, ReqAborted, ReqError, Router, SseServer, bs, enhanceIncomingMessage, enhanceServerResponse };
export type { BSQuestionOptions, ConfigOptions, Cookie, CorsOptions, CsrfChecksOptions, EndpointCallback, EndpointOptions, ExpressMiddleware, HealthcheckCallback, HttpConfig, Middleware, ReqOptions, ReqRes, RouterMatch, RouterMatchFunc, SecurityHeadersOptions, ServerRequest, ServerResponse, SseServerOptions };
