import type { IProtocolCacheEntry, IProtocolDistribution } from './metrics-types.js';
import type { IAcmeOptions, ISmartProxyChallengeOptions, ISmartProxyOptions, ISmartProxySecurityPolicy } from './interfaces.js';
import type {
  IRouteAction,
  IRouteConfig,
  IRouteMatch,
  IRouteTarget,
  ITargetMatch,
  IRouteUdp,
} from './route-types.js';

export type TRustHeaderMatchers = Record<string, string>;

export interface IRustRouteMatch extends Omit<IRouteMatch, 'headers'> {
  headers?: TRustHeaderMatchers;
}

export interface IRustTargetMatch extends Omit<ITargetMatch, 'headers'> {
  headers?: TRustHeaderMatchers;
}

export interface IRustRouteTarget extends Omit<IRouteTarget, 'host' | 'port' | 'match'> {
  host: string | string[];
  port: number | 'preserve';
  match?: IRustTargetMatch;
}

export interface IRustRouteUdp extends Omit<IRouteUdp, 'maxSessionsPerIP'> {
  maxSessionsPerIp?: number;
}

export interface IRustDefaultConfig extends Omit<NonNullable<ISmartProxyOptions['defaults']>, 'preserveSourceIP'> {
  preserveSourceIp?: boolean;
}

export interface IRustRouteAction
  extends Omit<IRouteAction, 'targets' | 'socketHandler' | 'datagramHandler' | 'forwardingEngine' | 'nftables' | 'udp'> {
  targets?: IRustRouteTarget[];
  udp?: IRustRouteUdp;
}

export interface IRustRouteConfig extends Omit<IRouteConfig, 'match' | 'action'> {
  match: IRustRouteMatch;
  action: IRustRouteAction;
}

export interface IRustAcmeOptions extends Omit<IAcmeOptions, 'routeForwards'> {}

export interface IRustChallengeOptions extends Required<Pick<
  ISmartProxyChallengeOptions,
  'cookieSigningKey' | 'pendingCookieName' | 'clearanceCookieName' | 'reservedPathPrefix' | 'relaySocketPath' | 'relayTimeoutMs' | 'pendingTtlSeconds'
>> {}

export interface IRustProxyOptions {
  routes: IRustRouteConfig[];
  preserveSourceIp?: boolean;
  trustedProxyIPs?: string[];
  sendProxyProtocol?: boolean;
  defaults?: IRustDefaultConfig;
  connectionTimeout?: number;
  initialDataTimeout?: number;
  socketTimeout?: number;
  inactivityCheckInterval?: number;
  maxConnectionLifetime?: number;
  inactivityTimeout?: number;
  gracefulShutdownTimeout?: number;
  noDelay?: boolean;
  keepAlive?: boolean;
  keepAliveInitialDelay?: number;
  maxPendingDataSize?: number;
  disableInactivityCheck?: boolean;
  enableKeepAliveProbes?: boolean;
  enableDetailedLogging?: boolean;
  enableTlsDebugLogging?: boolean;
  enableRandomizedTimeouts?: boolean;
  maxConnectionsPerIp?: number;
  connectionRateLimitPerMinute?: number;
  keepAliveTreatment?: ISmartProxyOptions['keepAliveTreatment'];
  keepAliveInactivityMultiplier?: number;
  extendedKeepAliveLifetime?: number;
  metrics?: ISmartProxyOptions['metrics'];
  securityPolicy?: ISmartProxySecurityPolicy;
  challenge?: IRustChallengeOptions;
  acme?: IRustAcmeOptions;
}

export interface IRustStatistics {
  activeConnections: number;
  totalConnections: number;
  routesCount: number;
  listeningPorts: number[];
  uptimeSeconds: number;
}

export interface IRustCertificateStatus {
  domain: string;
  source: string;
  expiresAt: number;
  isValid: boolean;
}

export interface IRustThroughputSample {
  timestampMs: number;
  bytesIn: number;
  bytesOut: number;
}

export interface IRustRouteMetrics {
  activeConnections: number;
  totalConnections: number;
  bytesIn: number;
  bytesOut: number;
  throughputInBytesPerSec: number;
  throughputOutBytesPerSec: number;
  throughputRecentInBytesPerSec: number;
  throughputRecentOutBytesPerSec: number;
}

export interface IRustIpMetrics {
  activeConnections: number;
  totalConnections: number;
  bytesIn: number;
  bytesOut: number;
  throughputInBytesPerSec: number;
  throughputOutBytesPerSec: number;
  domainRequests: Record<string, number>;
}

export interface IRustBackendMetrics {
  activeConnections: number;
  totalConnections: number;
  protocol: string;
  connectErrors: number;
  handshakeErrors: number;
  requestErrors: number;
  totalConnectTimeUs: number;
  connectCount: number;
  poolHits: number;
  poolMisses: number;
  h2Failures: number;
}

export interface IRustHttpDomainRequestMetrics {
  requestsPerSecond: number;
  requestsLastMinute: number;
}

export interface IRustMetricsSnapshot {
  activeConnections: number;
  totalConnections: number;
  bytesIn: number;
  bytesOut: number;
  throughputInBytesPerSec: number;
  throughputOutBytesPerSec: number;
  throughputRecentInBytesPerSec: number;
  throughputRecentOutBytesPerSec: number;
  routes: Record<string, IRustRouteMetrics>;
  ips: Record<string, IRustIpMetrics>;
  backends: Record<string, IRustBackendMetrics>;
  throughputHistory: IRustThroughputSample[];
  totalHttpRequests: number;
  httpRequestsPerSec: number;
  httpRequestsPerSecRecent: number;
  httpDomainRequests: Record<string, IRustHttpDomainRequestMetrics>;
  activeUdpSessions: number;
  totalUdpSessions: number;
  totalDatagramsIn: number;
  totalDatagramsOut: number;
  detectedProtocols: IProtocolCacheEntry[];
  frontendProtocols: IProtocolDistribution;
  backendProtocols: IProtocolDistribution;
}
