import { describe, it, expect, vi, beforeEach } from 'vitest';
import { toolSearchTool } from '../../../src/tools/tool-search.js';

// Mock toolRegistry
vi.mock('../../../src/tools/registry.js', () => ({
  toolRegistry: {
    search: vi.fn(),
  },
}));

import { toolRegistry } from '../../../src/tools/registry.js';

describe('toolSearchTool', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  describe('metadata', () => {
    it('工具名为 tool_search', () => {
      expect(toolSearchTool.name).toBe('tool_search');
    });

    it('有描述信息', () => {
      expect(toolSearchTool.description).toBeDefined();
      expect(toolSearchTool.description.length).toBeGreaterThan(0);
    });

    it('描述中包含功能类别', () => {
      expect(toolSearchTool.description).toContain('文件操作');
      expect(toolSearchTool.description).toContain('目录操作');
      expect(toolSearchTool.description).toContain('Shell');
    });

    it('有 query 参数', () => {
      expect(toolSearchTool.parameters.query).toBeDefined();
      expect(toolSearchTool.parameters.query.type).toBe('string');
      expect(toolSearchTool.parameters.query.required).toBe(true);
    });

    it('metadata 设置正确', () => {
      expect(toolSearchTool.metadata).toBeDefined();
      expect(toolSearchTool.metadata?.category).toBe('core');
      expect(toolSearchTool.metadata?.deferLoading).toBe(false);
    });

    it('metadata 包含搜索关键词', () => {
      expect(toolSearchTool.metadata?.keywords).toContain('search');
      expect(toolSearchTool.metadata?.keywords).toContain('搜索');
    });
  });

  describe('execute', () => {
    it('空 query 返回错误', async () => {
      const result = await toolSearchTool.execute({ query: '' });

      expect(result.success).toBe(false);
      expect(result.error).toBe('请提供搜索关键词');
    });

    it('空白 query 返回错误', async () => {
      const result = await toolSearchTool.execute({ query: '   ' });

      expect(result.success).toBe(false);
      expect(result.error).toBe('请提供搜索关键词');
    });

    it('undefined query 返回错误', async () => {
      const result = await toolSearchTool.execute({});

      expect(result.success).toBe(false);
      expect(result.error).toBe('请提供搜索关键词');
    });

    it('没有匹配结果时返回提示', async () => {
      vi.mocked(toolRegistry.search).mockReturnValue([]);

      const result = await toolSearchTool.execute({ query: 'nonexistent' });

      expect(result.success).toBe(true);
      expect(result.output).toContain('没有找到');
      expect(result.output).toContain('nonexistent');
    });

    it('有匹配结果时返回工具列表', async () => {
      vi.mocked(toolRegistry.search).mockReturnValue([
        { name: 'read_file', description: '读取文件', category: 'filesystem' },
        { name: 'write_file', description: '写入文件', category: 'filesystem' },
      ] as any);

      const result = await toolSearchTool.execute({ query: '文件' });

      expect(result.success).toBe(true);
      expect(result.output).toContain('找到 2 个相关工具');
      expect(result.output).toContain('read_file');
      expect(result.output).toContain('write_file');
      expect(result.output).toContain('[filesystem]');
    });

    it('返回结果包含使用提示', async () => {
      vi.mocked(toolRegistry.search).mockReturnValue([
        { name: 'bash', description: '执行命令', category: 'shell' },
      ] as any);

      const result = await toolSearchTool.execute({ query: '命令' });

      expect(result.output).toContain('可以直接调用');
    });

    it('调用 registry.search 时传递正确参数', async () => {
      vi.mocked(toolRegistry.search).mockReturnValue([]);

      await toolSearchTool.execute({ query: '搜索关键词' });

      expect(toolRegistry.search).toHaveBeenCalledWith('搜索关键词', 5);
    });

    it('搜索结果格式化正确', async () => {
      vi.mocked(toolRegistry.search).mockReturnValue([
        { name: 'grep_content', description: '搜索文件内容', category: 'filesystem' },
      ] as any);

      const result = await toolSearchTool.execute({ query: 'grep' });

      expect(result.output).toContain('- grep_content: 搜索文件内容 [filesystem]');
    });

    it('多个搜索结果正确排列', async () => {
      vi.mocked(toolRegistry.search).mockReturnValue([
        { name: 'tool1', description: 'desc1', category: 'cat1' },
        { name: 'tool2', description: 'desc2', category: 'cat2' },
        { name: 'tool3', description: 'desc3', category: 'cat3' },
      ] as any);

      const result = await toolSearchTool.execute({ query: 'test' });

      expect(result.output).toContain('找到 3 个相关工具');
      // 验证每个工具都在输出中
      expect(result.output).toContain('tool1');
      expect(result.output).toContain('tool2');
      expect(result.output).toContain('tool3');
    });
  });
});
