import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import { AtlasServer } from '../server.js';
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';

describe('AtlasServer', () => {
  let server: AtlasServer;
  let client: Client;
  let serverTransport: InMemoryTransport;
  let clientTransport: InMemoryTransport;

  beforeEach(async () => {
    server = new AtlasServer();
    
    // Register modules before connecting
    await (server as any).registerModules();
    
    // Create in-memory transports for testing
    const transports = InMemoryTransport.createLinkedPair();
    serverTransport = transports[0];
    clientTransport = transports[1];
    
    // Connect server
    const serverReady = (server as any).server.connect(serverTransport);
    
    // Connect client
    client = new Client({
      name: 'test-client',
      version: '1.0.0',
    }, {
      capabilities: {},
    });
    const clientReady = client.connect(clientTransport);
    
    // Wait for both to be ready
    await Promise.all([serverReady, clientReady]);
  });
  
  afterEach(async () => {
    await client.close();
    await (server as any).server.close();
  });

  describe('Initialization', () => {
    it('should create server with correct name and version', async () => {
      // Check that the server was created
      expect(server).toBeDefined();
      expect((server as any).server).toBeDefined();
    });

    it('should register required capabilities', async () => {
      // Capabilities are registered when modules are loaded
      expect((server as any).server).toBeDefined();
      // The actual capability check would be done through client requests
    });
  });

  describe('Tool Registration', () => {
    it('should register core tools', async () => {
      const response = await client.listTools();
      expect(response.tools).toBeDefined();
      expect(response.tools.length).toBeGreaterThan(0);
      
      // Check for specific tools
      const toolNames = response.tools.map((t: any) => t.name);
      expect(toolNames).toContain('init_project');
      expect(toolNames).toContain('create_kanban_board');
      expect(toolNames).toContain('add_kanban_task');
      expect(toolNames).toContain('generate_readme');
      expect(toolNames).toContain('setup_repository');
    });
  });

  describe('Resource Registration', () => {
    it('should register core resources', async () => {
      const response = await client.listResources();
      expect(response.resources).toBeDefined();
      expect(response.resources.length).toBeGreaterThan(0);
      
      // Check for specific resources
      const resourceUris = response.resources.map((r: any) => r.uri);
      expect(resourceUris).toContain('atlas://kanban/boards');
      expect(resourceUris).toContain('atlas://docs/templates');
      expect(resourceUris).toContain('atlas://project/status');
    });
  });

  describe('Prompt Registration', () => {
    it('should register core prompts', async () => {
      const response = await client.listPrompts();
      expect(response.prompts).toBeDefined();
      expect(response.prompts.length).toBeGreaterThan(0);
      
      // Check for specific prompts
      const promptNames = response.prompts.map((p: any) => p.name);
      expect(promptNames).toContain('startup_pitch');
      expect(promptNames).toContain('architecture_review');
      expect(promptNames).toContain('sprint_planning');
    });
  });

  describe('Module Integration', () => {
    it('should integrate kanban module tools', async () => {
      const response = await client.listTools();
      
      // Check for kanban-specific tools
      const toolNames = response.tools.map((t: any) => t.name);
      expect(toolNames).toContain('list_kanban_boards');
      expect(toolNames).toContain('move_kanban_task');
    });

    it('should integrate development module tools', async () => {
      const response = await client.listTools();
      
      // Check for development-specific tools
      const toolNames = response.tools.map((t: any) => t.name);
      expect(toolNames).toContain('create_feature');
      expect(toolNames).toContain('write_test');
      expect(toolNames).toContain('start_tdd_session');
      expect(toolNames).toContain('run_tests');
      expect(toolNames).toContain('enforce_tdd');
    });
  });
});