const express  = require('express');
const { spawn } = require('child_process');
const path     = require('path');
const router   = express.Router();

const PANEL_DIR  = path.join(__dirname, '..');
const TEST_FILE  = path.join(PANEL_DIR, 'tests', 'panel.test.js');
const fs         = require('fs');

// Stream test output via Server-Sent Events
router.get('/run', (req, res) => {
  const pass = (req.query.pass || '').trim();
  if (!pass) {
    return res.status(400).json({ error: 'pass query param required' });
  }

  if (!fs.existsSync(TEST_FILE)) {
    return res.status(404).json({ error: 'Test file not found at tests/panel.test.js' });
  }

  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
  res.flushHeaders();

  const send = (data) => res.write(`data: ${JSON.stringify(data)}\n\n`);

  send({ type: 'start', ts: Date.now() });

  const child = spawn(
    process.execPath,
    ['--test', '--test-concurrency=1', TEST_FILE],
    {
      cwd: PANEL_DIR,
      env: { ...process.env, TEST_PASS: pass, TEST_BASE: `http://localhost:${process.env.PORT || 4080}` },
      timeout: 600000
    }
  );

  const parseLine = (line) => {
    // node:test TAP output — parse pass/fail markers
    const trimmed = line.trim();
    if (!trimmed) return null;

    if (/^# tests \d+/.test(trimmed))  return { type: 'summary', line: trimmed };
    if (/^# pass \d+/.test(trimmed))   return { type: 'summary', line: trimmed };
    if (/^# fail \d+/.test(trimmed))   return { type: 'summary', line: trimmed };
    if (/^ok \d+/.test(trimmed))       return { type: 'pass',    line: trimmed };
    if (/^not ok \d+/.test(trimmed))   return { type: 'fail',    line: trimmed };
    if (/^# /.test(trimmed))           return { type: 'section', line: trimmed.slice(2) };
    return { type: 'raw', line: trimmed };
  };

  let buf = '';
  const onData = (chunk) => {
    buf += chunk.toString();
    const lines = buf.split('\n');
    buf = lines.pop(); // keep incomplete last line
    for (const line of lines) {
      const parsed = parseLine(line);
      if (parsed) send(parsed);
    }
  };

  child.stdout.on('data', onData);
  child.stderr.on('data', onData);

  child.on('close', (code) => {
    if (buf.trim()) {
      const parsed = parseLine(buf);
      if (parsed) send(parsed);
    }
    send({ type: 'done', code });
    res.end();
  });

  req.on('close', () => child.kill());
});

module.exports = router;
