import { describe, it, expect } from 'vitest';
import { createServer } from 'node:http';
import { fetchDiscovery } from './discovery.js';

async function startMock(
  handler: (req: import('http').IncomingMessage, body: string, res: import('http').ServerResponse) => void,
): Promise<{ origin: string; close: () => Promise<void> }> {
  const server = createServer((req, res) => {
    const chunks: Buffer[] = [];
    req.on('data', (c) => chunks.push(c));
    req.on('end', () => handler(req, Buffer.concat(chunks).toString(), res));
  });
  await new Promise<void>((resolve) => server.listen(0, '127.0.0.1', resolve));
  const port = (server.address() as { port: number }).port;
  return {
    origin: `http://127.0.0.1:${port}`,
    close: () => new Promise((r) => server.close(() => r())),
  };
}

describe('discovery (mock-backed)', () => {
  it('fetchDiscovery returns endpoints and fingerprint', async () => {
    let mockOrigin: string | undefined;
    const mock = await startMock((req, _body, res) => {
      if (req.url === '/.well-known/oauth-authorization-server') {
        res.setHeader('content-type', 'application/json');
        res.end(JSON.stringify({
          issuer: mockOrigin,
          authorization_endpoint: `${mockOrigin}/authorize`,
          token_endpoint: `${mockOrigin}/token`,
        }));
      } else {
        res.statusCode = 404;
        res.end();
      }
    });
    mockOrigin = mock.origin;
    try {
      const meta = await fetchDiscovery(mock.origin + '/mcp', { insecureLocalTestMode: true });
      expect(meta.authorizationEndpoint).toContain('/authorize');
      expect(meta.tokenEndpoint).toContain('/token');
      expect(meta.fingerprint).toHaveLength(64); // sha256 hex
    } finally {
      await mock.close();
    }
  });

  it('rejects discovery when endpoints have different origin than MCP url', async () => {
    const mock = await startMock((req, _body, res) => {
      if (req.url === '/.well-known/oauth-authorization-server') {
        res.setHeader('content-type', 'application/json');
        res.end(JSON.stringify({
          issuer: 'https://evil.example',
          authorization_endpoint: 'https://evil.example/authorize',
          token_endpoint: 'https://evil.example/token',
        }));
      } else {
        res.statusCode = 404;
        res.end();
      }
    });
    try {
      await expect(
        fetchDiscovery(mock.origin + '/mcp', { insecureLocalTestMode: true }),
      ).rejects.toThrow(/origin/i);
    } finally {
      await mock.close();
    }
  });
});
