import { describe, it, expect, beforeAll } from 'vitest';
import http from 'node:http';
import { isMcplocalRunning } from './mcp-client.js';

const MCPLOCAL_URL = process.env['MCPLOCAL_URL'] ?? 'http://localhost:3200';

let available = false;

function fetchJson<T>(urlPath: string, method = 'GET', body?: unknown): Promise<T | null> {
  return new Promise((resolve) => {
    const payload = body !== undefined ? JSON.stringify(body) : undefined;
    const req = http.request(`${MCPLOCAL_URL}${urlPath}`, {
      method,
      timeout: 5000,
      headers: payload ? { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) } : {},
    }, (res) => {
      const chunks: Buffer[] = [];
      res.on('data', (chunk: Buffer) => chunks.push(chunk));
      res.on('end', () => {
        try {
          resolve(JSON.parse(Buffer.concat(chunks).toString()) as T);
        } catch {
          resolve(null);
        }
      });
    });
    req.on('error', () => resolve(null));
    req.on('timeout', () => { req.destroy(); resolve(null); });
    if (payload) req.write(payload);
    req.end();
  });
}

beforeAll(async () => {
  available = await isMcplocalRunning();
});

describe('Hot-reload smoke tests', () => {
  describe('GET /proxymodels/stages', () => {
    it('returns list of stages with source', async () => {
      if (!available) return;

      const stages = await fetchJson<Array<{ name: string; source: string }>>('/proxymodels/stages');
      expect(stages).not.toBeNull();
      expect(Array.isArray(stages)).toBe(true);
      expect(stages!.length).toBeGreaterThan(0);

      // Should have built-in stages
      const passthrough = stages!.find((s) => s.name === 'passthrough');
      expect(passthrough).toBeDefined();
      expect(passthrough!.source).toBe('built-in');
    });
  });

  describe('POST /proxymodels/reload', () => {
    it('reloads stages and returns count', async () => {
      if (!available) return;

      const result = await fetchJson<{ loaded: number }>('/proxymodels/reload', 'POST');
      expect(result).not.toBeNull();
      expect(typeof result!.loaded).toBe('number');
    });
  });
});
