import * as plugins from './plugins.js';

/** Domain configuration with per-domain allowed port ranges */
export interface IDomainConfig {
  domains: string[]; // Glob patterns for domain(s)
  allowedIPs: string[]; // Glob patterns for allowed IPs
  blockedIPs?: string[]; // Glob patterns for blocked IPs
  targetIPs?: string[]; // If multiple targetIPs are given, use round robin.
  portRanges?: Array<{ from: number; to: number }>; // Optional port ranges
  // Allow domain-specific timeout override
  connectionTimeout?: number; // Connection timeout override (ms)

  // NetworkProxy integration options for this specific domain
  useNetworkProxy?: boolean; // Whether to use NetworkProxy for this domain
  networkProxyPort?: number; // Override default NetworkProxy port for this domain
}

/** Port proxy settings including global allowed port ranges */
export interface IPortProxySettings {
  fromPort: number;
  toPort: number;
  targetIP?: string; // Global target host to proxy to, defaults to 'localhost'
  domainConfigs: IDomainConfig[];
  sniEnabled?: boolean;
  defaultAllowedIPs?: string[];
  defaultBlockedIPs?: string[];
  preserveSourceIP?: boolean;

  // TLS options
  pfx?: Buffer;
  key?: string | Buffer | Array<Buffer | string>;
  passphrase?: string;
  cert?: string | Buffer | Array<string | Buffer>;
  ca?: string | Buffer | Array<string | Buffer>;
  ciphers?: string;
  honorCipherOrder?: boolean;
  rejectUnauthorized?: boolean;
  secureProtocol?: string;
  servername?: string;
  minVersion?: string;
  maxVersion?: string;

  // Timeout settings
  initialDataTimeout?: number; // Timeout for initial data/SNI (ms), default: 60000 (60s)
  socketTimeout?: number; // Socket inactivity timeout (ms), default: 3600000 (1h)
  inactivityCheckInterval?: number; // How often to check for inactive connections (ms), default: 60000 (60s)
  maxConnectionLifetime?: number; // Default max connection lifetime (ms), default: 86400000 (24h)
  inactivityTimeout?: number; // Inactivity timeout (ms), default: 14400000 (4h)

  gracefulShutdownTimeout?: number; // (ms) maximum time to wait for connections to close during shutdown
  globalPortRanges: Array<{ from: number; to: number }>; // Global allowed port ranges
  forwardAllGlobalRanges?: boolean; // When true, forwards all connections on global port ranges to the global targetIP

  // Socket optimization settings
  noDelay?: boolean; // Disable Nagle's algorithm (default: true)
  keepAlive?: boolean; // Enable TCP keepalive (default: true)
  keepAliveInitialDelay?: number; // Initial delay before sending keepalive probes (ms)
  maxPendingDataSize?: number; // Maximum bytes to buffer during connection setup

  // Enhanced features
  disableInactivityCheck?: boolean; // Disable inactivity checking entirely
  enableKeepAliveProbes?: boolean; // Enable TCP keep-alive probes
  enableDetailedLogging?: boolean; // Enable detailed connection logging
  enableTlsDebugLogging?: boolean; // Enable TLS handshake debug logging
  enableRandomizedTimeouts?: boolean; // Randomize timeouts slightly to prevent thundering herd
  allowSessionTicket?: boolean; // Allow TLS session ticket for reconnection (default: true)

  // Rate limiting and security
  maxConnectionsPerIP?: number; // Maximum simultaneous connections from a single IP
  connectionRateLimitPerMinute?: number; // Max new connections per minute from a single IP

  // Enhanced keep-alive settings
  keepAliveTreatment?: 'standard' | 'extended' | 'immortal'; // How to treat keep-alive connections
  keepAliveInactivityMultiplier?: number; // Multiplier for inactivity timeout for keep-alive connections
  extendedKeepAliveLifetime?: number; // Extended lifetime for keep-alive connections (ms)

  // NetworkProxy integration
  useNetworkProxy?: number[]; // Array of ports to forward to NetworkProxy
  networkProxyPort?: number; // Port where NetworkProxy is listening (default: 8443)

  // ACME certificate management options
  acme?: {
    enabled?: boolean; // Whether to enable automatic certificate management
    port?: number; // Port to listen on for ACME challenges (default: 80)
    contactEmail?: string; // Email for Let's Encrypt account
    useProduction?: boolean; // Whether to use Let's Encrypt production (default: false for staging)
    renewThresholdDays?: number; // Days before expiry to renew certificates (default: 30)
    autoRenew?: boolean; // Whether to automatically renew certificates (default: true)
    certificateStore?: string; // Directory to store certificates (default: ./certs)
    skipConfiguredCerts?: boolean; // Skip domains that already have certificates configured
  };
}

/**
 * Enhanced connection record
 */
export interface IConnectionRecord {
  id: string; // Unique connection identifier
  incoming: plugins.net.Socket;
  outgoing: plugins.net.Socket | null;
  incomingStartTime: number;
  outgoingStartTime?: number;
  outgoingClosedTime?: number;
  lockedDomain?: string; // Used to lock this connection to the initial SNI
  connectionClosed: boolean; // Flag to prevent multiple cleanup attempts
  cleanupTimer?: NodeJS.Timeout; // Timer for max lifetime/inactivity
  lastActivity: number; // Last activity timestamp for inactivity detection
  pendingData: Buffer[]; // Buffer to hold data during connection setup
  pendingDataSize: number; // Track total size of pending data

  // Enhanced tracking fields
  bytesReceived: number; // Total bytes received
  bytesSent: number; // Total bytes sent
  remoteIP: string; // Remote IP (cached for logging after socket close)
  localPort: number; // Local port (cached for logging)
  isTLS: boolean; // Whether this connection is a TLS connection
  tlsHandshakeComplete: boolean; // Whether the TLS handshake is complete
  hasReceivedInitialData: boolean; // Whether initial data has been received
  domainConfig?: IDomainConfig; // Associated domain config for this connection

  // Keep-alive tracking
  hasKeepAlive: boolean; // Whether keep-alive is enabled for this connection
  inactivityWarningIssued?: boolean; // Whether an inactivity warning has been issued
  incomingTerminationReason?: string | null; // Reason for incoming termination
  outgoingTerminationReason?: string | null; // Reason for outgoing termination

  // NetworkProxy tracking
  usingNetworkProxy?: boolean; // Whether this connection is using a NetworkProxy

  // Renegotiation handler
  renegotiationHandler?: (chunk: Buffer) => void; // Handler for renegotiation detection

  // Browser connection tracking
  isBrowserConnection?: boolean; // Whether this connection appears to be from a browser
  domainSwitches?: number; // Number of times the domain has been switched on this connection
}