import { describe, it, expect, vi } from 'vitest';
import { refreshUpstreams } from '../src/discovery.js';
import { McpRouter } from '../src/router.js';

function mockMcpdClient(servers: Array<{ id: string; name: string; transport: string }>) {
  const client = {
    baseUrl: 'http://test:3100',
    token: 'test-token',
    get: vi.fn(async () => servers),
    post: vi.fn(async () => ({ result: {} })),
    put: vi.fn(),
    delete: vi.fn(),
    forward: vi.fn(),
    withTimeout: vi.fn(() => client),
    withHeaders: vi.fn(() => client),
  };
  return client;
}

describe('refreshUpstreams', () => {
  it('registers mcpd servers as upstreams', async () => {
    const router = new McpRouter();
    const client = mockMcpdClient([
      { id: 'srv-1', name: 'slack', transport: 'stdio' },
      { id: 'srv-2', name: 'github', transport: 'stdio' },
    ]);

    const registered = await refreshUpstreams(router, client as any);
    expect(registered).toEqual(['slack', 'github']);
    expect(router.getUpstreamNames()).toContain('slack');
    expect(router.getUpstreamNames()).toContain('github');
  });

  it('removes stale upstreams', async () => {
    const router = new McpRouter();
    // First refresh: 2 servers
    const client1 = mockMcpdClient([
      { id: 'srv-1', name: 'slack', transport: 'stdio' },
      { id: 'srv-2', name: 'github', transport: 'stdio' },
    ]);
    await refreshUpstreams(router, client1 as any);
    expect(router.getUpstreamNames()).toHaveLength(2);

    // Second refresh: only 1 server
    const client2 = mockMcpdClient([
      { id: 'srv-1', name: 'slack', transport: 'stdio' },
    ]);
    await refreshUpstreams(router, client2 as any);
    expect(router.getUpstreamNames()).toEqual(['slack']);
  });

  it('does not duplicate existing upstreams', async () => {
    const router = new McpRouter();
    const client = mockMcpdClient([
      { id: 'srv-1', name: 'slack', transport: 'stdio' },
    ]);

    await refreshUpstreams(router, client as any);
    await refreshUpstreams(router, client as any);
    expect(router.getUpstreamNames()).toEqual(['slack']);
  });

  it('handles empty server list', async () => {
    const router = new McpRouter();
    const client = mockMcpdClient([]);

    const registered = await refreshUpstreams(router, client as any);
    expect(registered).toEqual([]);
    expect(router.getUpstreamNames()).toHaveLength(0);
  });
});
