import { Request, Response, NextFunction } from 'express';
import { IncomingHttpHeaders } from 'http';

/**
 * Represents a single brand entry from User-Agent Client Hints
 * @see https://wicg.github.io/ua-client-hints/
 */
interface ClientHintBrand {
    brand: string;
    version: string;
}
/**
 * Parsed User-Agent Client Hints data from HTTP headers
 * Maps to the NavigatorUAData interface exposed by browsers
 */
interface ClientHints {
    brands: ClientHintBrand[];
    mobile: boolean;
    platform: string;
    platformVersion: string;
    architecture: string;
    bitness: string;
    model: string;
    fullVersionList: ClientHintBrand[];
}
interface AgentDetails extends Record<string, unknown> {
    isYaBrowser: boolean;
    isAuthoritative: boolean;
    isMobile: boolean;
    isMobileNative: boolean;
    isTablet: boolean;
    isiPad: boolean;
    isiPod: boolean;
    isiPhone: boolean;
    isiPhoneNative: boolean;
    isAndroid: boolean;
    isAndroidNative: boolean;
    isBlackberry: boolean;
    isOpera: boolean;
    isIE: boolean;
    isEdge: boolean;
    isIECompatibilityMode: boolean;
    isSafari: boolean;
    isFirefox: boolean;
    isWebkit: boolean;
    isChrome: boolean;
    isKonqueror: boolean;
    isOmniWeb: boolean;
    isSeaMonkey: boolean;
    isFlock: boolean;
    isAmaya: boolean;
    isPhantomJS: boolean;
    isEpiphany: boolean;
    isDesktop: boolean;
    isWindows: boolean;
    isLinux: boolean;
    isLinux64: boolean;
    isMac: boolean;
    isChromeOS: boolean;
    isBada: boolean;
    isSamsung: boolean;
    isRaspberry: boolean;
    isBot: boolean;
    botName: string;
    isCurl: boolean;
    isAndroidTablet: boolean;
    isWinJs: boolean;
    isKindleFire: boolean;
    isSilk: boolean;
    isCaptive: boolean;
    isSmartTV: boolean;
    isUC: boolean;
    isFacebook: boolean;
    isAlamoFire: boolean;
    isElectron: boolean;
    silkAccelerated: boolean;
    browser: string;
    version: string | number;
    os: string;
    platform: string;
    geoIp: Record<string, string | string[]>;
    source: string;
    isWechat: boolean;
    isWindowsPhone: boolean;
    electronVersion: string;
    SilkAccelerated?: boolean;
    /** DuckDuckGo browser detected via Client Hints brand or WebKit UA pattern */
    isDuckDuckGo: boolean;
    /** Parsed User-Agent Client Hints when available */
    clientHints: ClientHints | null;
}
type HeadersLike = Partial<Record<string, string | string[] | undefined>>;
declare class UserAgent {
    private readonly versions;
    private readonly browsers;
    private readonly os;
    private readonly platform;
    Agent: AgentDetails;
    constructor();
    reset(): this;
    testNginxGeoIP(headers: HeadersLike | IncomingHttpHeaders): this;
    /** Maximum header length to process (prevents DoS from oversized headers) */
    private static readonly MAX_HEADER_LENGTH;
    /** Maximum number of brands to parse from a brand list */
    private static readonly MAX_BRAND_COUNT;
    /**
     * Parse User-Agent Client Hints from HTTP headers
     * @see https://wicg.github.io/ua-client-hints/
     */
    parseClientHints(headers: HeadersLike | IncomingHttpHeaders): ClientHints | null;
    /**
     * Test for DuckDuckGo browser using both Client Hints and UA string patterns
     * - Chromium platforms (Android, Windows): Sec-CH-UA brand "DuckDuckGo"
     * - WebKit platforms (iOS, macOS): UA string ends with " Ddg/X.Y.Z"
     */
    testDuckDuckGo(): void;
    testBot(): void;
    testSmartTV(): void;
    testMobile(): void;
    testAndroidTablet(): void;
    testTablet(): void;
    testCompatibilityMode(): void;
    testSilk(): string | false;
    testKindleFire(): string | false;
    testCaptiveNetwork(): string | false;
    testWebkit(): void;
    testWechat(): void;
    parse(source: string): AgentDetails;
    /**
     * Hydrate agent from UA string and HTTP headers (including Client Hints)
     * This method should be preferred when headers are available as it enables
     * detection of browsers that use Client Hints (e.g., DuckDuckGo on Chromium)
     */
    hydrateFromHeaders(source: string, headers: HeadersLike | IncomingHttpHeaders): this;
    hydrate(source: string): this;
    private getBrowser;
    private getBrowserVersion;
    private getWechatVersion;
    private getDuckDuckGoVersion;
    private getElectronVersion;
    private getOS;
    private getPlatform;
}

declare global {
    namespace Express {
        interface Request {
            useragent?: AgentDetails;
        }
    }
}
interface UserAgentAugmentedRequest extends Request {
    useragent?: ReturnType<UserAgent['parse']>;
    headers: IncomingHttpHeaders & Record<string, string | string[] | undefined>;
}
declare const useragent: UserAgent;
type UserAgentMiddleware = (req: Request, res: Response, next: NextFunction) => void;
declare const express: () => UserAgentMiddleware;
declare const useragentMiddleware: () => UserAgentMiddleware;
declare const defaultExport: UserAgent & {
    express: () => UserAgentMiddleware;
    UserAgent: typeof UserAgent;
};

export { type AgentDetails, type ClientHintBrand, type ClientHints, type HeadersLike, UserAgent, type UserAgentAugmentedRequest, type UserAgentMiddleware, defaultExport as default, express, useragent, useragentMiddleware };
