import type { IWgPeerConfig } from './smartvpn.interfaces.js';

// ============================================================================
// WireGuard .conf file generator
// ============================================================================

export interface IWgClientConfOptions {
  /** Client private key (base64) */
  privateKey: string;
  /** Client TUN address with prefix (e.g. 10.8.0.2/24) */
  address: string;
  /** DNS servers */
  dns?: string[];
  /** TUN MTU */
  mtu?: number;
  /** Server peer config */
  peer: {
    publicKey: string;
    presharedKey?: string;
    endpoint: string;
    allowedIps: string[];
    persistentKeepalive?: number;
  };
}

export interface IWgServerConfOptions {
  /** Server private key (base64) */
  privateKey: string;
  /** Server TUN address with prefix (e.g. 10.8.0.1/24) */
  address: string;
  /** UDP listen port */
  listenPort: number;
  /** DNS servers */
  dns?: string[];
  /** TUN MTU */
  mtu?: number;
  /** Enable NAT — adds PostUp/PostDown iptables rules */
  enableNat?: boolean;
  /** Network interface for NAT (e.g. eth0). Auto-detected if omitted. */
  natInterface?: string;
  /** Configured peers */
  peers: IWgPeerConfig[];
}

/**
 * Generates standard WireGuard .conf files compatible with wg-quick,
 * WireGuard iOS/Android apps, and other standard WireGuard clients.
 */
export class WgConfigGenerator {
  /**
   * Generate a client .conf file content.
   */
  public static generateClientConfig(opts: IWgClientConfOptions): string {
    const lines: string[] = [];

    lines.push('[Interface]');
    lines.push(`PrivateKey = ${opts.privateKey}`);
    lines.push(`Address = ${opts.address}`);
    if (opts.dns && opts.dns.length > 0) {
      lines.push(`DNS = ${opts.dns.join(', ')}`);
    }
    if (opts.mtu) {
      lines.push(`MTU = ${opts.mtu}`);
    }

    lines.push('');
    lines.push('[Peer]');
    lines.push(`PublicKey = ${opts.peer.publicKey}`);
    if (opts.peer.presharedKey) {
      lines.push(`PresharedKey = ${opts.peer.presharedKey}`);
    }
    lines.push(`Endpoint = ${opts.peer.endpoint}`);
    lines.push(`AllowedIPs = ${opts.peer.allowedIps.join(', ')}`);
    if (opts.peer.persistentKeepalive) {
      lines.push(`PersistentKeepalive = ${opts.peer.persistentKeepalive}`);
    }

    lines.push('');
    return lines.join('\n');
  }

  /**
   * Generate a server .conf file content.
   */
  public static generateServerConfig(opts: IWgServerConfOptions): string {
    const lines: string[] = [];

    lines.push('[Interface]');
    lines.push(`PrivateKey = ${opts.privateKey}`);
    lines.push(`Address = ${opts.address}`);
    lines.push(`ListenPort = ${opts.listenPort}`);
    if (opts.dns && opts.dns.length > 0) {
      lines.push(`DNS = ${opts.dns.join(', ')}`);
    }
    if (opts.mtu) {
      lines.push(`MTU = ${opts.mtu}`);
    }
    if (opts.enableNat) {
      const iface = opts.natInterface || 'eth0';
      lines.push(`PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ${iface} -j MASQUERADE`);
      lines.push(`PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ${iface} -j MASQUERADE`);
    }

    for (const peer of opts.peers) {
      lines.push('');
      lines.push('[Peer]');
      lines.push(`PublicKey = ${peer.publicKey}`);
      if (peer.presharedKey) {
        lines.push(`PresharedKey = ${peer.presharedKey}`);
      }
      lines.push(`AllowedIPs = ${peer.allowedIps.join(', ')}`);
      if (peer.endpoint) {
        lines.push(`Endpoint = ${peer.endpoint}`);
      }
      if (peer.persistentKeepalive) {
        lines.push(`PersistentKeepalive = ${peer.persistentKeepalive}`);
      }
    }

    lines.push('');
    return lines.join('\n');
  }
}
