const dgram = require('dgram');
const fs = require('fs');
const path = require('path');

// Load settings
function loadSettings(settingsPath = 'settings.json') {
  try {
    const data = fs.readFileSync(settingsPath, 'utf8');
    return JSON.parse(data);
  } catch (error) {
    console.error(`Failed to load settings from ${settingsPath}:`, error.message);
    process.exit(1);
  }
}

// Create the server
function startForwarder(settings) {
  const server = dgram.createSocket('udp4');
  const { listenPort, listenAddress = '0.0.0.0', destinations = [] } = settings;

  if (!listenPort) {
    console.error('Error: listenPort is required in settings.json');
    process.exit(1);
  }

  if (destinations.length === 0) {
    console.error('Error: At least one destination is required in settings.json');
    process.exit(1);
  }

  // Incoming UDP message handler
  server.on('message', (msg) => {

    // Forward to all destinations using the shared client socket
    destinations.forEach((dest, index) => {
      if (!dest.host || !dest.port) {
        console.warn(`Destination ${index + 1} missing host or port, skipping`);
        return;
      }

      forwardClient.send(msg, dest.port, dest.host, (err) => {
        if (err) {
          console.error(`Failed to forward to ${dest.host}:${dest.port}:`, err.message);
        }
      });
    });
  });

  // Error handler
  server.on('error', (err) => {
    console.error('Server error:', err);
    server.close();
    process.exit(1);
  });

  // Listening handler
  server.on('listening', () => {
    const address = server.address();
    console.log(`UDP Forwarder listening on ${address.address}:${address.port}`);
    console.log(`Forwarding to ${destinations.length} destination(s):`);
    destinations.forEach((dest, index) => {
      const label = dest.label ? ` (${dest.label})` : '';
      console.log(`  ${index + 1}. ${dest.host}:${dest.port}${label}`);
    });
  });

  // Bind to listen port
  server.bind(listenPort, listenAddress);

  // Create a single client socket to reuse for forwarding so the
  // destination sees a consistent source port (avoids counting many clients).
  const forwardClient = dgram.createSocket('udp4');

  // Graceful shutdown
  process.on('SIGINT', () => {
    console.log('\nShutting down forwarder...');
    server.close();
    try { forwardClient.close(); } catch (e) {}
    process.exit(0);
  });
}

// Main
const settingsPath = process.argv[2] || 'settings.json';
const settings = loadSettings(settingsPath);
startForwarder(settings);
