/**
 * MCP Manager 测试
 * 测试不需要实际连接的功能
 */

import { describe, it, expect, vi, afterEach } from 'vitest';
import { MCPManager, getMCPManager, resetMCPManager } from '../../../src/mcp/manager.js';
import type { MCPConfig } from '../../../src/mcp/types.js';

describe('MCPManager', () => {
  afterEach(async () => {
    resetMCPManager();
  });

  describe('基础状态', () => {
    it('初始状态应该是未初始化', () => {
      const manager = new MCPManager();
      expect(manager.isInitialized()).toBe(false);
    });

    it('初始时没有工具', () => {
      const manager = new MCPManager();
      expect(manager.getTools()).toEqual([]);
    });

    it('初始时没有服务器状态', () => {
      const manager = new MCPManager();
      expect(manager.getServerStatuses()).toEqual([]);
    });
  });

  describe('配置处理', () => {
    it('空配置不应该连接任何服务器', async () => {
      const manager = new MCPManager();
      await manager.initialize({});
      expect(manager.isInitialized()).toBe(true);
      expect(manager.getTools()).toEqual([]);
    });

    it('禁用的服务器应该显示在状态中', async () => {
      const manager = new MCPManager();
      const config: MCPConfig = {
        mcp: {
          disabled: {
            type: 'local',
            command: ['echo'],
            enabled: false,
          },
        },
      };
      await manager.initialize(config);
      const statuses = manager.getServerStatuses();
      expect(statuses).toHaveLength(1);
      expect(statuses[0].name).toBe('disabled');
      expect(statuses[0].status).toBe('disabled');
    });
  });

  describe('工具名解析', () => {
    it('无效的工具名格式应返回错误', async () => {
      const manager = new MCPManager();
      await manager.initialize({});

      const result = await manager.callTool('invalidname', {});
      expect(result.success).toBe(false);
      expect(result.isError).toBe(true);
      expect((result.content[0] as { text: string }).text).toContain('Invalid tool name');
    });

    it('服务器未连接时应返回错误', async () => {
      const manager = new MCPManager();
      await manager.initialize({});

      const result = await manager.callTool('server-tool', {});
      expect(result.success).toBe(false);
      expect(result.isError).toBe(true);
      expect((result.content[0] as { text: string }).text).toContain('not connected');
    });
  });

  describe('reconnect', () => {
    it('服务器不存在时应抛出错误', async () => {
      const manager = new MCPManager();
      await manager.initialize({ mcp: {} });

      await expect(manager.reconnect('nonexistent')).rejects.toThrow('Server not found');
    });
  });

  describe('setServerEnabled', () => {
    it('服务器不存在时应抛出错误', async () => {
      const manager = new MCPManager();
      await manager.initialize({ mcp: {} });

      await expect(manager.setServerEnabled('nonexistent', true)).rejects.toThrow(
        'Server not found'
      );
    });
  });

  describe('shutdown', () => {
    it('空初始化后可以安全关闭', async () => {
      const manager = new MCPManager();
      await manager.initialize({});
      await manager.shutdown();
      expect(manager.isInitialized()).toBe(false);
    });

    it('未初始化时可以安全关闭', async () => {
      const manager = new MCPManager();
      await manager.shutdown();
      expect(manager.isInitialized()).toBe(false);
    });
  });

  describe('事件发射', () => {
    it('应该是 EventEmitter 实例', () => {
      const manager = new MCPManager();
      expect(typeof manager.on).toBe('function');
      expect(typeof manager.emit).toBe('function');
    });

    it('应该支持事件监听', () => {
      const manager = new MCPManager();
      const callback = vi.fn();
      manager.on('tools:changed', callback);
      manager.emit('tools:changed');
      expect(callback).toHaveBeenCalled();
    });
  });
});

describe('getMCPManager / resetMCPManager', () => {
  afterEach(() => {
    resetMCPManager();
  });

  it('应该返回单例实例', () => {
    const manager1 = getMCPManager();
    const manager2 = getMCPManager();
    expect(manager1).toBe(manager2);
  });

  it('重置后应该返回新实例', () => {
    const manager1 = getMCPManager();
    resetMCPManager();
    const manager2 = getMCPManager();
    expect(manager1).not.toBe(manager2);
  });

  it('重置的实例应该是未初始化状态', () => {
    const manager1 = getMCPManager();
    resetMCPManager();
    const manager2 = getMCPManager();
    expect(manager2.isInitialized()).toBe(false);
  });
});
