import type { LookupAddress } from 'node:dns';
import type { AgentOptions, ClientRequest, Agent as HttpAgent, OutgoingHttpHeaders } from 'node:http';
import type { Agent as HttpsAgent } from 'node:https';
import type { ClientHttp2Stream } from 'node:http2';
import type { SecureVersion } from 'node:tls';

export const enum HTTP_STATUS {
    CONTINUE = 100,
    SWITCHING_PROTOCOL = 101,
    PROCESSING = 102,
    EARLY_HINTS = 103,
    OK = 200,
    CREATED = 201,
    ACCEPTED = 202,
    NON_AUTHORITATIVE_INFORMATION = 203,
    NO_CONTENT = 204,
    RESET_CONTENT = 205,
    PARTIAL_CONTENT = 206,
    MULTIPLE_CHOICES = 300,
    MOVED_PERMANENTLY = 301,
    FOUND = 302,
    SEE_OTHER = 303,
    NOT_MODIFIED = 304,
    USE_PROXY = 305,
    TEMPORARY_REDIRECT = 307,
    PERMANENT_REDIRECT = 308,
    BAD_REQUEST = 400,
    UNAUTHORIZED = 401,
    PAYMENT_REQUIRED = 402,
    FORBIDDEN = 403,
    NOT_FOUND = 404,
    METHOD_NOT_ALLOWED = 405,
    NOT_ACCEPTABLE = 406,
    PROXY_AUTHENTICATION_REQUIRED = 407,
    REQUEST_TIMEOUT = 408,
    CONFLICT = 409,
    GONE = 410,
    LENGTH_REQUIRED = 411,
    PRECONDITION_FAILED = 412,
    PAYLOAD_TOO_LARGE = 413,
    REQUEST_URI_TOO_LONG = 414,
    UNSUPPORTED_MEDIA_TYPE = 415,
    RANGE_NOT_SATISFIABLE = 416,
    EXPECTATION_FAILED = 417,
    MISDIRECTED_REQUEST = 421,
    UNPROCESSABLE_ENTITY = 422,
    LOCKED = 423,
    FAILED_DEPENDENCY = 424,
    TOO_EARLY = 425,
    UPGRADE_REQUIRED = 426,
    PRECONDITION_REQUIRED = 428,
    TOO_MANY_REQUESTS = 429,
    REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
    UNAVAILABLE_FOR_LEGAL_REASONS = 451,
    SSL_CERTIFICATE_ERROR = 495,
    SSL_CERTIFICATE_REQUIRED = 496,
    CLIENT_CLOSED_REQUEST = 499,
    INTERNAL_SERVER_ERROR = 500,
    NOT_IMPLEMENTED = 501,
    BAD_GATEWAY = 502,
    SERVICE_UNAVAILABLE = 503,
    GATEWAY_TIMEOUT = 504,
    HTTP_VERSION_NOT_SUPPORTED = 505,
    VARIANT_ALSO_NEGOTIATES = 506,
    INSUFFICIENT_STORAGE = 507,
    LOOP_DETECTED = 508,
    BANDWIDTH_LIMIT_EXCEEDED = 509,
    NOT_EXTENDED = 510,
    NETWORK_AUTHENTICATION_REQUIRED = 511,
    WEB_SERVER_IS_DOWN = 521,
    CONNECTION_TIMED_OUT = 522,
    ORIGIN_IS_UNREACHABLE = 523,
    A_TIMEOUT_OCCURRED = 524,
    SSL_HANDSHAKE_FAILED = 525,
    INVALID_SSL_CERTIFICATE = 526
}

export const enum QUERY_RESULT {
    FAIL,
    OK,
    TIMEOUT
}

export interface HeadersAction {
    headers?: OutgoingHttpHeaders | Headers;
}

export interface HttpAgentSettings extends HttpAgentOptions {
    http?: HttpAgent;
    https?: HttpsAgent;
    keepAlive?: boolean;
}

export interface SecureConfig<T = string, U = T> {
    ca?: T;
    key?: U;
    cert?: T;
    passphrase?: U;
    ciphers?: string;
    version?: SecureVersion;
}

export interface ServerPort<T = number | string> {
    port?: T;
}

export interface ServerSecure extends SecureConfig, ServerPort {}

export interface AuthValue {
    username?: string;
    password?: string;
}

export type HttpRequestClient = ClientRequest | ClientHttp2Stream;
export type HttpHeaders = OutgoingHttpHeaders | Headers;
export type HttpOutgoingHeaders = ObjectMap<HttpHeaders>;
export type HttpAgentOptions = Pick<AgentOptions, "timeout" | "maxSockets" | "maxTotalSockets" | "keepAliveMsecs" | "maxFreeSockets" | "proxyEnv">;
export type HttpProtocolVersion = 1 | 2 | 3;
export type InternetProtocolVersion = 0 | 4 | 6;
export type LookupCallback = (err: NodeJS.ErrnoException | null, address: string | LookupAddress[], family?: number) => void;