/**
 * Socket Tracker Utility
 * Provides standardized socket cleanup with proper listener and timer management
 */

import type { Socket } from 'node:net';

export type SocketTracked = {
  cleanup: () => void;
  addListener: <E extends string>(event: E, listener: (...args: any[]) => void) => void;
  addTimer: (t: NodeJS.Timeout | null | undefined) => void;
  safeDestroy: (reason?: Error) => void;
};

/**
 * Create a socket tracker to manage listeners and timers
 * Ensures proper cleanup and prevents memory leaks
 */
export function createSocketTracker(socket: Socket): SocketTracked {
  const listeners: Array<{ event: string; listener: (...args: any[]) => void }> = [];
  const timers: NodeJS.Timeout[] = [];
  let cleaned = false;

  const addListener = (event: string, listener: (...args: any[]) => void) => {
    socket.on(event, listener);
    listeners.push({ event, listener });
  };

  const addTimer = (t: NodeJS.Timeout | null | undefined) => {
    if (!t) return;
    timers.push(t);
    // Unref timer so it doesn't keep process alive
    if (typeof t.unref === 'function') {
      t.unref();
    }
  };

  const cleanup = () => {
    if (cleaned) return;
    cleaned = true;
    
    // Clear all tracked timers
    for (const t of timers) {
      clearTimeout(t);
    }
    timers.length = 0;
    
    // Remove all tracked listeners
    for (const { event, listener } of listeners) {
      socket.off(event, listener);
    }
    listeners.length = 0;
  };

  const safeDestroy = (reason?: Error) => {
    cleanup();
    if (!socket.destroyed) {
      socket.destroy(reason);
    }
  };

  return { cleanup, addListener, addTimer, safeDestroy };
}