/**
 * Route Helper Functions
 *
 * This file provides utility functions for creating route configurations for common scenarios.
 * These functions aim to simplify the creation of route configurations for typical use cases.
 *
 * This module includes helper functions for creating:
 * - HTTP routes (createHttpRoute)
 * - HTTPS routes with TLS termination (createHttpsTerminateRoute)
 * - HTTP to HTTPS redirects (createHttpToHttpsRedirect)
 * - HTTPS passthrough routes (createHttpsPassthroughRoute)
 * - Complete HTTPS servers with redirects (createCompleteHttpsServer)
 * - Load balancer routes (createLoadBalancerRoute)
 * - API routes (createApiRoute)
 * - WebSocket routes (createWebSocketRoute)
 * - Port mapping routes (createPortMappingRoute, createOffsetPortMappingRoute)
 * - Dynamic routing (createDynamicRoute, createSmartLoadBalancer)
 * - NFTables routes (createNfTablesRoute, createNfTablesTerminateRoute)
 */

import * as plugins from '../../../plugins.js';
import type { IRouteConfig, IRouteMatch, IRouteAction, IRouteTarget, TPortRange, IRouteContext } from '../models/route-types.js';

/**
 * Create an HTTP-only route configuration
 * @param domains Domain(s) to match
 * @param target Target host and port
 * @param options Additional route options
 * @returns Route configuration object
 */
export function createHttpRoute(
  domains: string | string[],
  target: { host: string | string[]; port: number },
  options: Partial<IRouteConfig> = {}
): IRouteConfig {
  // Create route match
  const match: IRouteMatch = {
    ports: options.match?.ports || 80,
    domains
  };

  // Create route action
  const action: IRouteAction = {
    type: 'forward',
    target
  };

  // Create the route config
  return {
    match,
    action,
    name: options.name || `HTTP Route for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
    ...options
  };
}

/**
 * Create an HTTPS route with TLS termination (including HTTP redirect to HTTPS)
 * @param domains Domain(s) to match
 * @param target Target host and port
 * @param options Additional route options
 * @returns Route configuration object
 */
export function createHttpsTerminateRoute(
  domains: string | string[],
  target: { host: string | string[]; port: number },
  options: {
    certificate?: 'auto' | { key: string; cert: string };
    httpPort?: number | number[];
    httpsPort?: number | number[];
    reencrypt?: boolean;
    name?: string;
    [key: string]: any;
  } = {}
): IRouteConfig {
  // Create route match
  const match: IRouteMatch = {
    ports: options.httpsPort || 443,
    domains
  };

  // Create route action
  const action: IRouteAction = {
    type: 'forward',
    target,
    tls: {
      mode: options.reencrypt ? 'terminate-and-reencrypt' : 'terminate',
      certificate: options.certificate || 'auto'
    }
  };

  // Create the route config
  return {
    match,
    action,
    name: options.name || `HTTPS Route for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
    ...options
  };
}

/**
 * Create an HTTP to HTTPS redirect route
 * @param domains Domain(s) to match
 * @param httpsPort HTTPS port to redirect to (default: 443)
 * @param options Additional route options
 * @returns Route configuration object
 */
export function createHttpToHttpsRedirect(
  domains: string | string[],
  httpsPort: number = 443,
  options: Partial<IRouteConfig> = {}
): IRouteConfig {
  // Create route match
  const match: IRouteMatch = {
    ports: options.match?.ports || 80,
    domains
  };

  // Create route action
  const action: IRouteAction = {
    type: 'socket-handler',
    socketHandler: SocketHandlers.httpRedirect(`https://{domain}:${httpsPort}{path}`, 301)
  };

  // Create the route config
  return {
    match,
    action,
    name: options.name || `HTTP to HTTPS Redirect for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
    ...options
  };
}

/**
 * Create an HTTPS passthrough route (SNI-based forwarding without TLS termination)
 * @param domains Domain(s) to match
 * @param target Target host and port
 * @param options Additional route options
 * @returns Route configuration object
 */
export function createHttpsPassthroughRoute(
  domains: string | string[],
  target: { host: string | string[]; port: number },
  options: Partial<IRouteConfig> = {}
): IRouteConfig {
  // Create route match
  const match: IRouteMatch = {
    ports: options.match?.ports || 443,
    domains
  };

  // Create route action
  const action: IRouteAction = {
    type: 'forward',
    target,
    tls: {
      mode: 'passthrough'
    }
  };

  // Create the route config
  return {
    match,
    action,
    name: options.name || `HTTPS Passthrough for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
    ...options
  };
}

/**
 * Create a complete HTTPS server with HTTP to HTTPS redirects
 * @param domains Domain(s) to match
 * @param target Target host and port
 * @param options Additional configuration options
 * @returns Array of two route configurations (HTTPS and HTTP redirect)
 */
export function createCompleteHttpsServer(
  domains: string | string[],
  target: { host: string | string[]; port: number },
  options: {
    certificate?: 'auto' | { key: string; cert: string };
    httpPort?: number | number[];
    httpsPort?: number | number[];
    reencrypt?: boolean;
    name?: string;
    [key: string]: any;
  } = {}
): IRouteConfig[] {
  // Create the HTTPS route
  const httpsRoute = createHttpsTerminateRoute(domains, target, options);
  
  // Create the HTTP redirect route
  const httpRedirectRoute = createHttpToHttpsRedirect(
    domains,
    // Extract the HTTPS port from the HTTPS route - ensure it's a number
    typeof options.httpsPort === 'number' ? options.httpsPort :
      Array.isArray(options.httpsPort) ? options.httpsPort[0] : 443,
    {
      // Set the HTTP port
      match: {
        ports: options.httpPort || 80,
        domains
      },
      name: `HTTP to HTTPS Redirect for ${Array.isArray(domains) ? domains.join(', ') : domains}`
    }
  );
  
  return [httpsRoute, httpRedirectRoute];
}

/**
 * Create a load balancer route (round-robin between multiple backend hosts)
 * @param domains Domain(s) to match
 * @param hosts Array of backend hosts to load balance between
 * @param port Backend port
 * @param options Additional route options
 * @returns Route configuration object
 */
export function createLoadBalancerRoute(
  domains: string | string[],
  hosts: string[],
  port: number,
  options: {
    tls?: {
      mode: 'passthrough' | 'terminate' | 'terminate-and-reencrypt';
      certificate?: 'auto' | { key: string; cert: string };
    };
    [key: string]: any;
  } = {}
): IRouteConfig {
  // Create route match
  const match: IRouteMatch = {
    ports: options.match?.ports || (options.tls ? 443 : 80),
    domains
  };

  // Create route target
  const target: IRouteTarget = {
    host: hosts,
    port
  };

  // Create route action
  const action: IRouteAction = {
    type: 'forward',
    target
  };

  // Add TLS configuration if provided
  if (options.tls) {
    action.tls = {
      mode: options.tls.mode,
      certificate: options.tls.certificate || 'auto'
    };
  }

  // Create the route config
  return {
    match,
    action,
    name: options.name || `Load Balancer for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
    ...options
  };
}

/**
 * Create an API route configuration
 * @param domains Domain(s) to match
 * @param apiPath API base path (e.g., "/api")
 * @param target Target host and port
 * @param options Additional route options
 * @returns Route configuration object
 */
export function createApiRoute(
  domains: string | string[],
  apiPath: string,
  target: { host: string | string[]; port: number },
  options: {
    useTls?: boolean;
    certificate?: 'auto' | { key: string; cert: string };
    addCorsHeaders?: boolean;
    httpPort?: number | number[];
    httpsPort?: number | number[];
    name?: string;
    [key: string]: any;
  } = {}
): IRouteConfig {
  // Normalize API path
  const normalizedPath = apiPath.startsWith('/') ? apiPath : `/${apiPath}`;
  const pathWithWildcard = normalizedPath.endsWith('/')
    ? `${normalizedPath}*`
    : `${normalizedPath}/*`;

  // Create route match
  const match: IRouteMatch = {
    ports: options.useTls
      ? (options.httpsPort || 443)
      : (options.httpPort || 80),
    domains,
    path: pathWithWildcard
  };

  // Create route action
  const action: IRouteAction = {
    type: 'forward',
    target
  };

  // Add TLS configuration if using HTTPS
  if (options.useTls) {
    action.tls = {
      mode: 'terminate',
      certificate: options.certificate || 'auto'
    };
  }

  // Add CORS headers if requested
  const headers: Record<string, Record<string, string>> = {};
  if (options.addCorsHeaders) {
    headers.response = {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type, Authorization',
      'Access-Control-Max-Age': '86400'
    };
  }

  // Create the route config
  return {
    match,
    action,
    headers: Object.keys(headers).length > 0 ? headers : undefined,
    name: options.name || `API Route ${normalizedPath} for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
    priority: options.priority || 100, // Higher priority for specific path matches
    ...options
  };
}

/**
 * Create a WebSocket route configuration
 * @param domains Domain(s) to match
 * @param wsPath WebSocket path (e.g., "/ws")
 * @param target Target WebSocket server host and port
 * @param options Additional route options
 * @returns Route configuration object
 */
export function createWebSocketRoute(
  domains: string | string[],
  wsPath: string,
  target: { host: string | string[]; port: number },
  options: {
    useTls?: boolean;
    certificate?: 'auto' | { key: string; cert: string };
    httpPort?: number | number[];
    httpsPort?: number | number[];
    pingInterval?: number;
    pingTimeout?: number;
    name?: string;
    [key: string]: any;
  } = {}
): IRouteConfig {
  // Normalize WebSocket path
  const normalizedPath = wsPath.startsWith('/') ? wsPath : `/${wsPath}`;

  // Create route match
  const match: IRouteMatch = {
    ports: options.useTls
      ? (options.httpsPort || 443)
      : (options.httpPort || 80),
    domains,
    path: normalizedPath
  };

  // Create route action
  const action: IRouteAction = {
    type: 'forward',
    target,
    websocket: {
      enabled: true,
      pingInterval: options.pingInterval || 30000, // 30 seconds
      pingTimeout: options.pingTimeout || 5000    // 5 seconds
    }
  };

  // Add TLS configuration if using HTTPS
  if (options.useTls) {
    action.tls = {
      mode: 'terminate',
      certificate: options.certificate || 'auto'
    };
  }

  // Create the route config
  return {
    match,
    action,
    name: options.name || `WebSocket Route ${normalizedPath} for ${Array.isArray(domains) ? domains.join(', ') : domains}`,
    priority: options.priority || 100, // Higher priority for WebSocket routes
    ...options
  };
}

/**
 * Create a helper function that applies a port offset
 * @param offset The offset to apply to the matched port
 * @returns A function that adds the offset to the matched port
 */
export function createPortOffset(offset: number): (context: IRouteContext) => number {
  return (context: IRouteContext) => context.port + offset;
}

/**
 * Create a port mapping route with context-based port function
 * @param options Port mapping route options
 * @returns Route configuration object
 */
export function createPortMappingRoute(options: {
  sourcePortRange: TPortRange;
  targetHost: string | string[] | ((context: IRouteContext) => string | string[]);
  portMapper: (context: IRouteContext) => number;
  name?: string;
  domains?: string | string[];
  priority?: number;
  [key: string]: any;
}): IRouteConfig {
  // Create route match
  const match: IRouteMatch = {
    ports: options.sourcePortRange,
    domains: options.domains
  };

  // Create route action
  const action: IRouteAction = {
    type: 'forward',
    target: {
      host: options.targetHost,
      port: options.portMapper
    }
  };

  // Create the route config
  return {
    match,
    action,
    name: options.name || `Port Mapping Route for ${options.domains || 'all domains'}`,
    priority: options.priority,
    ...options
  };
}

/**
 * Create a simple offset port mapping route
 * @param options Offset port mapping route options
 * @returns Route configuration object
 */
export function createOffsetPortMappingRoute(options: {
  ports: TPortRange;
  targetHost: string | string[];
  offset: number;
  name?: string;
  domains?: string | string[];
  priority?: number;
  [key: string]: any;
}): IRouteConfig {
  return createPortMappingRoute({
    sourcePortRange: options.ports,
    targetHost: options.targetHost,
    portMapper: (context) => context.port + options.offset,
    name: options.name || `Offset Mapping (${options.offset > 0 ? '+' : ''}${options.offset}) for ${options.domains || 'all domains'}`,
    domains: options.domains,
    priority: options.priority,
    ...options
  });
}

/**
 * Create a dynamic route with context-based host and port mapping
 * @param options Dynamic route options
 * @returns Route configuration object
 */
export function createDynamicRoute(options: {
  ports: TPortRange;
  targetHost: (context: IRouteContext) => string | string[];
  portMapper: (context: IRouteContext) => number;
  name?: string;
  domains?: string | string[];
  path?: string;
  clientIp?: string[];
  priority?: number;
  [key: string]: any;
}): IRouteConfig {
  // Create route match
  const match: IRouteMatch = {
    ports: options.ports,
    domains: options.domains,
    path: options.path,
    clientIp: options.clientIp
  };

  // Create route action
  const action: IRouteAction = {
    type: 'forward',
    target: {
      host: options.targetHost,
      port: options.portMapper
    }
  };

  // Create the route config
  return {
    match,
    action,
    name: options.name || `Dynamic Route for ${options.domains || 'all domains'}`,
    priority: options.priority,
    ...options
  };
}

/**
 * Create a smart load balancer with dynamic domain-based backend selection
 * @param options Smart load balancer options
 * @returns Route configuration object
 */
export function createSmartLoadBalancer(options: {
  ports: TPortRange;
  domainTargets: Record<string, string | string[]>;
  portMapper: (context: IRouteContext) => number;
  name?: string;
  defaultTarget?: string | string[];
  priority?: number;
  [key: string]: any;
}): IRouteConfig {
  // Extract all domain keys to create the match criteria
  const domains = Object.keys(options.domainTargets);

  // Create the smart host selector function
  const hostSelector = (context: IRouteContext) => {
    const domain = context.domain || '';
    return options.domainTargets[domain] || options.defaultTarget || 'localhost';
  };

  // Create route match
  const match: IRouteMatch = {
    ports: options.ports,
    domains
  };

  // Create route action
  const action: IRouteAction = {
    type: 'forward',
    target: {
      host: hostSelector,
      port: options.portMapper
    }
  };

  // Create the route config
  return {
    match,
    action,
    name: options.name || `Smart Load Balancer for ${domains.join(', ')}`,
    priority: options.priority,
    ...options
  };
}

/**
 * Create an NFTables-based route for high-performance packet forwarding
 * @param nameOrDomains Name or domain(s) to match
 * @param target Target host and port
 * @param options Additional route options
 * @returns Route configuration object
 */
export function createNfTablesRoute(
  nameOrDomains: string | string[],
  target: { host: string; port: number | 'preserve' },
  options: {
    ports?: TPortRange;
    protocol?: 'tcp' | 'udp' | 'all';
    preserveSourceIP?: boolean;
    ipAllowList?: string[];
    ipBlockList?: string[];
    maxRate?: string;
    priority?: number;
    useTls?: boolean;
    tableName?: string;
    useIPSets?: boolean;
    useAdvancedNAT?: boolean;
  } = {}
): IRouteConfig {
  // Determine if this is a name or domain
  let name: string;
  let domains: string | string[] | undefined;
  
  if (Array.isArray(nameOrDomains) || (typeof nameOrDomains === 'string' && nameOrDomains.includes('.'))) {
    domains = nameOrDomains;
    name = Array.isArray(nameOrDomains) ? nameOrDomains[0] : nameOrDomains;
  } else {
    name = nameOrDomains;
    domains = undefined; // No domains
  }
  
  // Create route match
  const match: IRouteMatch = {
    domains,
    ports: options.ports || 80
  };
  
  // Create route action
  const action: IRouteAction = {
    type: 'forward',
    target: {
      host: target.host,
      port: target.port
    },
    forwardingEngine: 'nftables',
    nftables: {
      protocol: options.protocol || 'tcp',
      preserveSourceIP: options.preserveSourceIP,
      maxRate: options.maxRate,
      priority: options.priority,
      tableName: options.tableName,
      useIPSets: options.useIPSets,
      useAdvancedNAT: options.useAdvancedNAT
    }
  };
  
  // Add TLS options if needed
  if (options.useTls) {
    action.tls = {
      mode: 'passthrough'
    };
  }
  
  // Create the route config
  const routeConfig: IRouteConfig = {
    name,
    match,
    action
  };
  
  // Add security if allowed or blocked IPs are specified
  if (options.ipAllowList?.length || options.ipBlockList?.length) {
    routeConfig.security = {
      ipAllowList: options.ipAllowList,
      ipBlockList: options.ipBlockList
    };
  }
  
  return routeConfig;
}

/**
 * Create an NFTables-based TLS termination route
 * @param nameOrDomains Name or domain(s) to match
 * @param target Target host and port
 * @param options Additional route options
 * @returns Route configuration object
 */
export function createNfTablesTerminateRoute(
  nameOrDomains: string | string[],
  target: { host: string; port: number | 'preserve' },
  options: {
    ports?: TPortRange;
    protocol?: 'tcp' | 'udp' | 'all';
    preserveSourceIP?: boolean;
    ipAllowList?: string[];
    ipBlockList?: string[];
    maxRate?: string;
    priority?: number;
    tableName?: string;
    useIPSets?: boolean;
    useAdvancedNAT?: boolean;
    certificate?: 'auto' | { key: string; cert: string };
  } = {}
): IRouteConfig {
  // Create basic NFTables route
  const route = createNfTablesRoute(
    nameOrDomains,
    target,
    {
      ...options,
      ports: options.ports || 443,
      useTls: false
    }
  );
  
  // Set TLS termination
  route.action.tls = {
    mode: 'terminate',
    certificate: options.certificate || 'auto'
  };
  
  return route;
}

/**
 * Create a complete NFTables-based HTTPS setup with HTTP redirect
 * @param nameOrDomains Name or domain(s) to match
 * @param target Target host and port
 * @param options Additional route options
 * @returns Array of two route configurations (HTTPS and HTTP redirect)
 */
export function createCompleteNfTablesHttpsServer(
  nameOrDomains: string | string[],
  target: { host: string; port: number | 'preserve' },
  options: {
    httpPort?: TPortRange;
    httpsPort?: TPortRange;
    protocol?: 'tcp' | 'udp' | 'all';
    preserveSourceIP?: boolean;
    ipAllowList?: string[];
    ipBlockList?: string[];
    maxRate?: string;
    priority?: number;
    tableName?: string;
    useIPSets?: boolean;
    useAdvancedNAT?: boolean;
    certificate?: 'auto' | { key: string; cert: string };
  } = {}
): IRouteConfig[] {
  // Create the HTTPS route using NFTables
  const httpsRoute = createNfTablesTerminateRoute(
    nameOrDomains,
    target,
    {
      ...options,
      ports: options.httpsPort || 443
    }
  );
  
  // Determine the domain(s) for HTTP redirect
  const domains = typeof nameOrDomains === 'string' && !nameOrDomains.includes('.') 
    ? undefined 
    : nameOrDomains;
  
  // Extract the HTTPS port for the redirect destination
  const httpsPort = typeof options.httpsPort === 'number' 
    ? options.httpsPort 
    : Array.isArray(options.httpsPort) && typeof options.httpsPort[0] === 'number' 
      ? options.httpsPort[0] 
      : 443;
  
  // Create the HTTP redirect route (this uses standard forwarding, not NFTables)
  const httpRedirectRoute = createHttpToHttpsRedirect(
    domains as any, // Type cast needed since domains can be undefined now
    httpsPort,
    {
      match: {
        ports: options.httpPort || 80,
        domains: domains as any // Type cast needed since domains can be undefined now
      },
      name: `HTTP to HTTPS Redirect for ${Array.isArray(domains) ? domains.join(', ') : domains || 'all domains'}`
    }
  );
  
  return [httpsRoute, httpRedirectRoute];
}

/**
 * Create a socket handler route configuration
 * @param domains Domain(s) to match
 * @param ports Port(s) to listen on
 * @param handler Socket handler function
 * @param options Additional route options
 * @returns Route configuration object
 */
export function createSocketHandlerRoute(
  domains: string | string[],
  ports: TPortRange,
  handler: (socket: plugins.net.Socket) => void | Promise<void>,
  options: {
    name?: string;
    priority?: number;
    path?: string;
  } = {}
): IRouteConfig {
  return {
    name: options.name || 'socket-handler-route',
    priority: options.priority !== undefined ? options.priority : 50,
    match: {
      domains,
      ports,
      ...(options.path && { path: options.path })
    },
    action: {
      type: 'socket-handler',
      socketHandler: handler
    }
  };
}

/**
 * Pre-built socket handlers for common use cases
 */
export const SocketHandlers = {
  /**
   * Simple echo server handler
   */
  echo: (socket: plugins.net.Socket, context: IRouteContext) => {
    socket.write('ECHO SERVER READY\n');
    socket.on('data', data => socket.write(data));
  },
  
  /**
   * TCP proxy handler
   */
  proxy: (targetHost: string, targetPort: number) => (socket: plugins.net.Socket, context: IRouteContext) => {
    const target = plugins.net.connect(targetPort, targetHost);
    socket.pipe(target);
    target.pipe(socket);
    socket.on('close', () => target.destroy());
    target.on('close', () => socket.destroy());
    target.on('error', (err) => {
      console.error('Proxy target error:', err);
      socket.destroy();
    });
  },
  
  /**
   * Line-based protocol handler
   */
  lineProtocol: (handler: (line: string, socket: plugins.net.Socket) => void) => (socket: plugins.net.Socket, context: IRouteContext) => {
    let buffer = '';
    socket.on('data', (data) => {
      buffer += data.toString();
      const lines = buffer.split('\n');
      buffer = lines.pop() || '';
      lines.forEach(line => {
        if (line.trim()) {
          handler(line.trim(), socket);
        }
      });
    });
  },
  
  /**
   * Simple HTTP response handler (for testing)
   */
  httpResponse: (statusCode: number, body: string) => (socket: plugins.net.Socket, context: IRouteContext) => {
    const response = [
      `HTTP/1.1 ${statusCode} ${statusCode === 200 ? 'OK' : 'Error'}`,
      'Content-Type: text/plain',
      `Content-Length: ${body.length}`,
      'Connection: close',
      '',
      body
    ].join('\r\n');
    
    socket.write(response);
    socket.end();
  },
  
  /**
   * Block connection immediately
   */
  block: (message?: string) => (socket: plugins.net.Socket, context: IRouteContext) => {
    const finalMessage = message || `Connection blocked from ${context.clientIp}`;
    if (finalMessage) {
      socket.write(finalMessage);
    }
    socket.end();
  },
  
  /**
   * HTTP block response
   */
  httpBlock: (statusCode: number = 403, message?: string) => (socket: plugins.net.Socket, context: IRouteContext) => {
    const defaultMessage = `Access forbidden for ${context.domain || context.clientIp}`;
    const finalMessage = message || defaultMessage;
    
    const response = [
      `HTTP/1.1 ${statusCode} ${finalMessage}`,
      'Content-Type: text/plain',
      `Content-Length: ${finalMessage.length}`,
      'Connection: close',
      '',
      finalMessage
    ].join('\r\n');
    
    socket.write(response);
    socket.end();
  },
  
  /**
   * HTTP redirect handler
   */
  httpRedirect: (locationTemplate: string, statusCode: number = 301) => (socket: plugins.net.Socket, context: IRouteContext) => {
    let buffer = '';
    
    socket.once('data', (data) => {
      buffer += data.toString();
      
      const lines = buffer.split('\r\n');
      const requestLine = lines[0];
      const [method, path] = requestLine.split(' ');
      
      const domain = context.domain || 'localhost';
      const port = context.port;
      
      let finalLocation = locationTemplate
        .replace('{domain}', domain)
        .replace('{port}', String(port))
        .replace('{path}', path)
        .replace('{clientIp}', context.clientIp);
      
      const message = `Redirecting to ${finalLocation}`;
      const response = [
        `HTTP/1.1 ${statusCode} ${statusCode === 301 ? 'Moved Permanently' : 'Found'}`,
        `Location: ${finalLocation}`,
        'Content-Type: text/plain',
        `Content-Length: ${message.length}`,
        'Connection: close',
        '',
        message
      ].join('\r\n');
      
      socket.write(response);
      socket.end();
    });
  },
  
  /**
   * HTTP server handler for ACME challenges and other HTTP needs
   */
  httpServer: (handler: (req: { method: string; url: string; headers: Record<string, string>; body?: string }, res: { status: (code: number) => void; header: (name: string, value: string) => void; send: (data: string) => void; end: () => void }) => void) => (socket: plugins.net.Socket, context: IRouteContext) => {
    let buffer = '';
    let requestParsed = false;
    
    socket.on('data', (data) => {
      if (requestParsed) return; // Only handle the first request
      
      buffer += data.toString();
      
      // Check if we have a complete HTTP request
      const headerEndIndex = buffer.indexOf('\r\n\r\n');
      if (headerEndIndex === -1) return; // Need more data
      
      requestParsed = true;
      
      // Parse the HTTP request
      const headerPart = buffer.substring(0, headerEndIndex);
      const bodyPart = buffer.substring(headerEndIndex + 4);
      
      const lines = headerPart.split('\r\n');
      const [method, url] = lines[0].split(' ');
      
      const headers: Record<string, string> = {};
      for (let i = 1; i < lines.length; i++) {
        const colonIndex = lines[i].indexOf(':');
        if (colonIndex > 0) {
          const name = lines[i].substring(0, colonIndex).trim().toLowerCase();
          const value = lines[i].substring(colonIndex + 1).trim();
          headers[name] = value;
        }
      }
      
      // Create request object
      const req = {
        method: method || 'GET',
        url: url || '/',
        headers,
        body: bodyPart
      };
      
      // Create response object
      let statusCode = 200;
      const responseHeaders: Record<string, string> = {};
      let ended = false;
      
      const res = {
        status: (code: number) => {
          statusCode = code;
        },
        header: (name: string, value: string) => {
          responseHeaders[name] = value;
        },
        send: (data: string) => {
          if (ended) return;
          ended = true;
          
          if (!responseHeaders['content-type']) {
            responseHeaders['content-type'] = 'text/plain';
          }
          responseHeaders['content-length'] = String(data.length);
          responseHeaders['connection'] = 'close';
          
          const statusText = statusCode === 200 ? 'OK' : 
                           statusCode === 404 ? 'Not Found' :
                           statusCode === 500 ? 'Internal Server Error' : 'Response';
          
          let response = `HTTP/1.1 ${statusCode} ${statusText}\r\n`;
          for (const [name, value] of Object.entries(responseHeaders)) {
            response += `${name}: ${value}\r\n`;
          }
          response += '\r\n';
          response += data;
          
          socket.write(response);
          socket.end();
        },
        end: () => {
          if (ended) return;
          ended = true;
          socket.write('HTTP/1.1 200 OK\r\nContent-Length: 0\r\nConnection: close\r\n\r\n');
          socket.end();
        }
      };
      
      try {
        handler(req, res);
        // Ensure response is sent even if handler doesn't call send()
        setTimeout(() => {
          if (!ended) {
            res.send('');
          }
        }, 1000);
      } catch (error) {
        if (!ended) {
          res.status(500);
          res.send('Internal Server Error');
        }
      }
    });
    
    socket.on('error', () => {
      if (!requestParsed) {
        socket.end();
      }
    });
  }
};