/**
 * Dashboard HTTP Server
 *
 * Serves the dashboard HTML, JSON API, and SSE events.
 * Zero external dependencies — uses Node.js built-in http module.
 */
import * as http from 'node:http';
import { getDashboardHTML } from './html.js';
import { gatherDashboardData } from './data.js';
const SSE_INTERVAL_MS = 4_000;
export function createDashboardServer(options) {
    const { port, storage, projectId, projectName } = options;
    const sseClients = new Set();
    let sseInterval = null;
    const html = getDashboardHTML(port);
    const server = http.createServer(async (req, res) => {
        const url = req.url || '/';
        // CORS headers for local development
        res.setHeader('Access-Control-Allow-Origin', '*');
        if (url === '/' || url === '/index.html') {
            res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
            res.end(html);
            return;
        }
        if (url === '/api/data') {
            try {
                const data = await gatherDashboardData(storage, projectId, projectName);
                res.writeHead(200, { 'Content-Type': 'application/json' });
                res.end(JSON.stringify(data));
            }
            catch (err) {
                res.writeHead(500, { 'Content-Type': 'application/json' });
                res.end(JSON.stringify({ error: 'Failed to gather data' }));
            }
            return;
        }
        if (url === '/api/events') {
            res.writeHead(200, {
                'Content-Type': 'text/event-stream',
                'Cache-Control': 'no-cache',
                'Connection': 'keep-alive',
            });
            // Send initial data
            try {
                const data = await gatherDashboardData(storage, projectId, projectName);
                res.write(`data: ${JSON.stringify(data)}\n\n`);
            }
            catch {
                // Will retry on next interval
            }
            sseClients.add(res);
            req.on('close', () => {
                sseClients.delete(res);
            });
            return;
        }
        // 404
        res.writeHead(404, { 'Content-Type': 'text/plain' });
        res.end('Not Found');
    });
    // Start SSE broadcast interval
    sseInterval = setInterval(async () => {
        if (sseClients.size === 0)
            return;
        try {
            const data = await gatherDashboardData(storage, projectId, projectName);
            const payload = `data: ${JSON.stringify(data)}\n\n`;
            for (const client of sseClients) {
                try {
                    client.write(payload);
                }
                catch {
                    sseClients.delete(client);
                }
            }
        }
        catch {
            // Data gathering failed, skip this cycle
        }
    }, SSE_INTERVAL_MS);
    const url = `http://localhost:${port}`;
    return new Promise((resolve, reject) => {
        server.on('error', (err) => {
            if (err.code === 'EADDRINUSE') {
                reject(new Error(`Port ${port} is already in use. Try --port <number> to use a different port.`));
            }
            else {
                reject(err);
            }
        });
        server.listen(port, '127.0.0.1', () => {
            resolve({
                server,
                url,
                close: () => {
                    return new Promise((resolveClose) => {
                        if (sseInterval)
                            clearInterval(sseInterval);
                        // Close all SSE connections
                        for (const client of sseClients) {
                            try {
                                client.end();
                            }
                            catch { /* ignore */ }
                        }
                        sseClients.clear();
                        server.close(() => resolveClose());
                    });
                },
            });
        });
    });
}
//# sourceMappingURL=server.js.map