import * as plugins from '../../../plugins.js';
import type { IRouteContext } from '../../../core/models/route-context.js';
export type { IRouteContext };
/**
 * Supported action types for route configurations
 */
export type TRouteActionType = 'forward' | 'socket-handler';
/**
 * Socket handler function type
 */
export type TSocketHandler = (socket: plugins.net.Socket, context: IRouteContext) => void | Promise<void>;
/**
 * TLS handling modes for route configurations
 */
export type TTlsMode = 'passthrough' | 'terminate' | 'terminate-and-reencrypt';
/**
 * Transport protocol for route matching
 */
export type TTransportProtocol = 'tcp' | 'udp' | 'all';
/**
 * Inbound PROXY protocol handling for a listener.
 */
export type TInboundProxyProtocolMode = 'reject' | 'optional' | 'required';
export interface IInboundProxyProtocolPolicy {
    mode: TInboundProxyProtocolMode;
    trustedProxyIPs?: string[];
}
/**
 * Port range specification format.
 * Supports: single number, array of numbers, array of ranges, or mixed arrays.
 */
export type TPortRange = number | Array<number | {
    from: number;
    to: number;
}>;
/**
 * Route match criteria for incoming requests
 */
export interface IRouteMatch {
    ports: TPortRange;
    transport?: TTransportProtocol;
    inboundProxyProtocol?: IInboundProxyProtocolPolicy;
    domains?: string | string[];
    path?: string;
    clientIp?: string[];
    tlsVersion?: string[];
    headers?: Record<string, string | RegExp>;
    protocol?: 'http' | 'tcp' | 'udp' | 'quic' | 'http3';
}
/**
 * Target-specific match criteria for sub-routing within a route
 */
export interface ITargetMatch {
    ports?: number[];
    path?: string;
    headers?: Record<string, string | RegExp>;
    method?: string[];
}
/**
 * Target configuration for forwarding with sub-matching and overrides
 */
export interface IRouteTarget {
    match?: ITargetMatch;
    host: string | string[] | ((context: IRouteContext) => string | string[]);
    port: number | 'preserve' | ((context: IRouteContext) => number);
    tls?: IRouteTls;
    websocket?: IRouteWebSocket;
    loadBalancing?: IRouteLoadBalancing;
    sendProxyProtocol?: boolean;
    headers?: IRouteHeaders;
    advanced?: IRouteAdvanced;
    backendTransport?: 'tcp' | 'udp';
    priority?: number;
}
/**
 * ACME configuration for automatic certificate provisioning
 */
export interface IRouteAcme {
    email: string;
    useProduction?: boolean;
    challengePort?: number;
    renewBeforeDays?: number;
}
/**
 * TLS configuration for route actions
 */
export interface IRouteTls {
    mode: TTlsMode;
    certificate?: 'auto' | {
        key: string;
        cert: string;
        ca?: string;
        keyFile?: string;
        certFile?: string;
    };
    acme?: IRouteAcme;
    versions?: string[];
    ciphers?: string;
    honorCipherOrder?: boolean;
    sessionTimeout?: number;
}
/**
 * Authentication options
 */
export interface IRouteAuthentication {
    type: 'basic' | 'digest' | 'oauth' | 'jwt';
    credentials?: {
        username: string;
        password: string;
    }[];
    realm?: string;
    jwtSecret?: string;
    jwtIssuer?: string;
    oauthProvider?: string;
    oauthClientId?: string;
    oauthClientSecret?: string;
    oauthRedirectUri?: string;
    options?: Record<string, unknown>;
}
/**
 * Security options for routes
 */
export interface IRouteSecurity {
    ipAllowList?: Array<string | {
        ip: string;
        domains: string[];
    }>;
    ipBlockList?: string[];
    maxConnections?: number;
    authentication?: IRouteAuthentication;
    rateLimit?: IRouteRateLimit;
    basicAuth?: {
        enabled: boolean;
        users: Array<{
            username: string;
            password: string;
        }>;
        realm?: string;
        excludePaths?: string[];
    };
    jwtAuth?: {
        enabled: boolean;
        secret: string;
        algorithm?: string;
        issuer?: string;
        audience?: string;
        expiresIn?: number;
        excludePaths?: string[];
    };
    vpn?: {
        /** Require authenticated VPN metadata from a trusted PROXY v2 TLV. */
        required?: boolean;
        /** Allowed VPN client IDs. Entries can be full-route or domain-scoped. */
        allowedClients?: Array<string | {
            clientId: string;
            domains: string[];
        }>;
        /** Allowed VPN tunnel IPs, kept for compatibility. Prefer allowedClients. */
        allowedAssignedIps?: string[];
    };
    /** Browser-facing challenge policy. SmartProxy enforces this in the HTTP path. */
    challenge?: plugins.smartchallenge.IRouteChallengeConfig;
}
/**
 * Static file server configuration
 */
export interface IRouteStaticFiles {
    root: string;
    index?: string[];
    headers?: Record<string, string>;
    directory?: string;
    indexFiles?: string[];
    cacheControl?: string;
    expires?: number;
    followSymlinks?: boolean;
    disableDirectoryListing?: boolean;
}
/**
 * Test route response configuration
 */
export interface IRouteTestResponse {
    status: number;
    headers: Record<string, string>;
    body: string;
}
/**
 * URL rewriting configuration
 */
export interface IRouteUrlRewrite {
    pattern: string;
    target: string;
    flags?: string;
    onlyRewritePath?: boolean;
}
/**
 * Advanced options for route actions
 */
export interface IRouteAdvanced {
    timeout?: number;
    headers?: Record<string, string>;
    keepAlive?: boolean;
    staticFiles?: IRouteStaticFiles;
    testResponse?: IRouteTestResponse;
    urlRewrite?: IRouteUrlRewrite;
}
/**
 * WebSocket configuration
 */
export interface IRouteWebSocket {
    enabled: boolean;
    pingInterval?: number;
    pingTimeout?: number;
    maxPayloadSize?: number;
    customHeaders?: Record<string, string>;
    subprotocols?: string[];
    rewritePath?: string;
    allowedOrigins?: string[];
    authenticateRequest?: boolean;
}
/**
 * Load balancing configuration
 */
export interface IRouteLoadBalancing {
    algorithm: 'round-robin' | 'least-connections' | 'ip-hash';
    healthCheck?: {
        path: string;
        interval: number;
        timeout: number;
        unhealthyThreshold: number;
        healthyThreshold: number;
    };
}
/**
 * Action configuration for route handling
 */
export interface IRouteAction {
    type: TRouteActionType;
    targets?: IRouteTarget[];
    tls?: IRouteTls;
    websocket?: IRouteWebSocket;
    loadBalancing?: IRouteLoadBalancing;
    advanced?: IRouteAdvanced;
    options?: {
        backendProtocol?: 'http1' | 'http2' | 'http3' | 'auto';
        [key: string]: any;
    };
    forwardingEngine?: 'node' | 'nftables';
    nftables?: INfTablesOptions;
    socketHandler?: TSocketHandler;
    datagramHandler?: TDatagramHandler;
    sendProxyProtocol?: boolean;
    udp?: IRouteUdp;
}
/**
 * Rate limiting configuration
 */
export type TRouteRateLimitExceededType = '429' | 'challenge';
export type TRouteRateLimitChallengeClearanceEffect = 'bypass-rate-limit' | 'none';
export interface IRouteRateLimitExceededPolicy {
    type: TRouteRateLimitExceededType;
    challenge?: plugins.smartchallenge.IRouteChallengeConfig;
    clearanceEffect?: TRouteRateLimitChallengeClearanceEffect;
}
export interface IRouteRateLimit {
    enabled: boolean;
    maxRequests: number;
    window: number;
    keyBy?: 'ip' | 'path' | 'header';
    headerName?: string;
    errorMessage?: string;
    onExceeded?: IRouteRateLimitExceededPolicy;
}
/**
 * NFTables-specific configuration options
 */
export interface INfTablesOptions {
    preserveSourceIP?: boolean;
    protocol?: 'tcp' | 'udp' | 'all';
    maxRate?: string;
    priority?: number;
    tableName?: string;
    useIPSets?: boolean;
    useAdvancedNAT?: boolean;
}
/**
 * CORS configuration for a route
 */
export interface IRouteCors {
    enabled: boolean;
    allowOrigin?: string | string[];
    allowMethods?: string;
    allowHeaders?: string;
    allowCredentials?: boolean;
    exposeHeaders?: string;
    maxAge?: number;
    preflight?: boolean;
}
/**
 * Headers configuration
 */
export interface IRouteHeaders {
    request?: Record<string, string>;
    response?: Record<string, string>;
    cors?: IRouteCors;
}
/**
 * The core unified configuration interface
 */
export interface IRouteConfig {
    id?: string;
    match: IRouteMatch;
    action: IRouteAction;
    headers?: IRouteHeaders;
    security?: IRouteSecurity;
    name?: string;
    description?: string;
    priority?: number;
    tags?: string[];
    enabled?: boolean;
}
/**
 * Handler for individual UDP datagrams.
 * Called for each incoming datagram on a socket-handler route with UDP transport.
 */
export type TDatagramHandler = (datagram: Buffer, info: IDatagramInfo, reply: (data: Buffer) => void) => void | Promise<void>;
/**
 * Metadata for a received UDP datagram
 */
export interface IDatagramInfo {
    /** Source IP address */
    sourceIp: string;
    /** Source port */
    sourcePort: number;
    /** Destination (local) port the datagram arrived on */
    destPort: number;
    /** Route context */
    context: IRouteContext;
}
/**
 * UDP-specific settings for route actions
 */
export interface IRouteUdp {
    /** Idle timeout for a UDP session/flow (keyed by src IP:port), in ms. Default: 60000 */
    sessionTimeout?: number;
    /** Max concurrent UDP sessions per source IP. Default: 1000 */
    maxSessionsPerIP?: number;
    /** Max accepted datagram size in bytes. Oversized datagrams are dropped. Default: 65535 */
    maxDatagramSize?: number;
    /** QUIC-specific configuration. When present, traffic is treated as QUIC. */
    quic?: IRouteQuic;
}
/**
 * QUIC and HTTP/3 settings
 */
export interface IRouteQuic {
    /** QUIC connection idle timeout in ms. Default: 30000 */
    maxIdleTimeout?: number;
    /** Max concurrent bidirectional streams per QUIC connection. Default: 100 */
    maxConcurrentBidiStreams?: number;
    /** Max concurrent unidirectional streams per QUIC connection. Default: 100 */
    maxConcurrentUniStreams?: number;
    /** Enable HTTP/3 over this QUIC endpoint. Default: false */
    enableHttp3?: boolean;
    /** Port to advertise in Alt-Svc header on TCP HTTP responses. Default: listening port */
    altSvcPort?: number;
    /** Max age for Alt-Svc advertisement in seconds. Default: 86400 */
    altSvcMaxAge?: number;
    /** Initial congestion window size in bytes. Default: implementation-defined */
    initialCongestionWindow?: number;
}
