import WebSocket, { WebSocketServer } from 'ws';
import https from 'https';
import fs from 'fs';

const PORT = Number.parseInt(process.env.DAEMON_PORT || '4551', 10);
const USE_TLS = process.env.DAEMON_TLS === '1';
const TLS_KEY_PATH = process.env.DAEMON_TLS_KEY_PATH;
const TLS_CERT_PATH = process.env.DAEMON_TLS_CERT_PATH;
const TLS_CA_PATH = process.env.DAEMON_TLS_CA_PATH; // optional

// Einfache In-Memory-Struktur für Verbindungen (für spätere Erweiterungen)
const connections = new Set();

function createServer() {
  let wss;

  if (USE_TLS) {
    if (!TLS_KEY_PATH || !TLS_CERT_PATH) {
      console.error('[Daemon] DAEMON_TLS=1 gesetzt, aber DAEMON_TLS_KEY_PATH/DAEMON_TLS_CERT_PATH fehlen.');
      process.exit(1);
    }
    const httpsServer = https.createServer({
      key: fs.readFileSync(TLS_KEY_PATH),
      cert: fs.readFileSync(TLS_CERT_PATH),
      ca: TLS_CA_PATH ? fs.readFileSync(TLS_CA_PATH) : undefined,
    });
    wss = new WebSocketServer({ server: httpsServer });
    httpsServer.listen(PORT, '0.0.0.0', () => {
      console.log(`[Daemon] WSS (TLS) Server gestartet auf Port ${PORT}`);
    });
  } else {
    wss = new WebSocketServer({ port: PORT });
    console.log(`[Daemon] WS (ohne TLS) Server startet auf Port ${PORT} ...`);
  }

  wss.on('connection', (ws, req) => {
    const peer = req.socket.remoteAddress + ':' + req.socket.remotePort;
    ws.isAlive = true;
    ws.userId = null;
    connections.add(ws);

    console.log(`[Daemon] Neue Verbindung von ${peer}`);

    ws.on('message', (message) => {
      try {
        if (message.toString() === 'pong') {
          // Client-Pong für unser Ping
          ws.isAlive = true;
          return;
        }

        const data = JSON.parse(message.toString());

        // Vom Frontend gesendet nach Verbindungsaufbau
        if (data.event === 'setUserId' && data.data?.userId) {
          ws.userId = data.data.userId;
          console.log(`[Daemon] setUserId erhalten: ${ws.userId}`);
          return;
        }

        // Admin-Dialog: WebSocket-Log anfordern
        if (data.event === 'getWebsocketLog') {
          const response = {
            event: 'getWebsocketLogResponse',
            entries: [] // aktuell keine Log-Historie implementiert
          };
          ws.send(JSON.stringify(response));
          return;
        }

        // Platzhalter für spätere Events
        // console.log('[Daemon] Unbekanntes Event:', data);
      } catch (err) {
        console.error('[Daemon] Fehler beim Verarbeiten einer Nachricht:', err);
      }
    });

    ws.on('close', () => {
      connections.delete(ws);
      console.log('[Daemon] Verbindung geschlossen');
    });

    ws.on('error', (err) => {
      console.error('[Daemon] WebSocket-Fehler (Verbindung):', err);
    });
  });

  // Einfache Ping/Pong-Mechanik, damit Verbindungen sauber erkannt werden
  const interval = setInterval(() => {
    for (const ws of connections) {
      if (ws.isAlive === false) {
        console.log('[Daemon] Verbindung wegen fehlendem Pong beendet');
        ws.terminate();
        connections.delete(ws);
        continue;
      }
      ws.isAlive = false;
      try {
        ws.send('ping');
      } catch (err) {
        console.error('[Daemon] Fehler beim Senden von Ping:', err);
      }
    }
  }, 30000);

  wss.on('close', () => {
    clearInterval(interval);
    connections.clear();
    console.log('[Daemon] Server gestoppt');
  });

  wss.on('error', (err) => {
    console.error('[Daemon] Server-Fehler:', err);
  });

  return wss;
}

createServer();


