/**
 * SSE endpoint for the MCP traffic inspector.
 *
 * GET /inspect?project=X&session=Y
 *
 * Streams TrafficEvents as SSE data lines. On connect, sends a snapshot
 * of active sessions and recent buffered events, then streams live.
 */

import type { FastifyInstance } from 'fastify';
import type { TrafficCapture, TrafficFilter } from './traffic.js';

export function registerInspectEndpoint(app: FastifyInstance, capture: TrafficCapture): void {
  app.get<{
    Querystring: { project?: string; session?: string };
  }>('/inspect', async (request, reply) => {
    const filter: TrafficFilter = {
      project: request.query.project,
      session: request.query.session,
    };

    // Set SSE headers
    reply.raw.writeHead(200, {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive',
      'X-Accel-Buffering': 'no', // Disable nginx buffering
    });

    // Send active sessions snapshot
    const sessions = capture.getActiveSessions();
    const filteredSessions = filter.project
      ? sessions.filter((s) => s.projectName === filter.project)
      : sessions;

    reply.raw.write(`event: sessions\ndata: ${JSON.stringify(filteredSessions)}\n\n`);

    // Send buffered events
    const buffered = capture.getBuffer(filter);
    for (const event of buffered) {
      reply.raw.write(`data: ${JSON.stringify(event)}\n\n`);
    }

    // Flush marker so client knows history is done
    reply.raw.write(`event: live\ndata: {}\n\n`);

    // Subscribe to live events
    const matchesFilter = (e: { projectName: string; sessionId: string }): boolean => {
      if (filter.project && e.projectName !== filter.project) return false;
      if (filter.session && e.sessionId !== filter.session) return false;
      return true;
    };

    const unsubscribe = capture.subscribe((event) => {
      if (!matchesFilter(event)) return;
      try {
        reply.raw.write(`data: ${JSON.stringify(event)}\n\n`);
      } catch {
        unsubscribe();
      }
    });

    // Keep-alive ping every 30s
    const keepAlive = setInterval(() => {
      try {
        reply.raw.write(': keepalive\n\n');
      } catch {
        clearInterval(keepAlive);
        unsubscribe();
      }
    }, 30_000);

    // Cleanup on disconnect
    request.raw.on('close', () => {
      clearInterval(keepAlive);
      unsubscribe();
    });

    // Hijack so Fastify doesn't try to send its own response
    reply.hijack();
  });
}
