import { describe, it, expect } from 'vitest';
import { matchesAnyPattern, normalizeToolName, parseToolName, buildToolDefsFromCache } from './tool-adapter.js';

describe('matchesAnyPattern', () => {
  it('matches wildcard with prefix', () => {
    expect(matchesAnyPattern('mcp__canva__generate', ['mcp__canva__*'])).toBe(true);
  });
  it('does not match different server', () => {
    expect(matchesAnyPattern('mcp__notion__x', ['mcp__canva__*'])).toBe(false);
  });
  it('matches exact names', () => {
    expect(matchesAnyPattern('mcp__canva__export', ['mcp__canva__export'])).toBe(true);
  });
  it('rejects empty tool suffix under wildcard', () => {
    expect(matchesAnyPattern('mcp__canva__', ['mcp__canva__*'])).toBe(false);
  });
});

describe('normalizeToolName / parseToolName', () => {
  it('normalizes', () => {
    expect(normalizeToolName('canva', 'generate_designs')).toBe('mcp__canva__generate_designs');
  });
  it('parses back', () => {
    expect(parseToolName('mcp__canva__generate_designs')).toEqual({
      serverId: 'canva',
      toolName: 'generate_designs',
    });
  });
  it('returns null for invalid prefix', () => {
    expect(parseToolName('WebFetch')).toBeNull();
  });
  it('rejects slug violations', () => {
    expect(parseToolName('mcp__BAD__ok')).toBeNull();
  });
  it('accepts camelCase tool names (remote MCP servers, e.g. NocoDB)', () => {
    expect(parseToolName('mcp__nocodb__createRecords')).toEqual({
      serverId: 'nocodb',
      toolName: 'createRecords',
    });
  });
});

describe('buildToolDefsFromCache', () => {
  const cache = [
    { serverId: 'canva', toolName: 'generate_designs', description: 'gen', inputSchema: '{"type":"object"}' },
    { serverId: 'canva', toolName: 'export_design', description: null, inputSchema: null },
    { serverId: 'notion', toolName: 'search', description: 'n', inputSchema: '{"type":"object"}' },
  ];
  const serverNames = new Map([['canva', 'Canva'], ['notion', 'Notion']]);

  it('filters by wildcard', () => {
    const defs = buildToolDefsFromCache(cache, ['mcp__canva__*'], serverNames);
    expect(defs.map((d) => d.function.name)).toEqual([
      'mcp__canva__generate_designs',
      'mcp__canva__export_design',
    ]);
  });
  it('prefixes description with [外部ツール: ... 提供]', () => {
    const defs = buildToolDefsFromCache(cache, ['mcp__canva__generate_designs'], serverNames);
    expect(defs[0].function.description).toMatch(/^\[外部ツール: Canva 提供\]/);
  });
  it('falls back to empty object schema when missing', () => {
    const defs = buildToolDefsFromCache(cache, ['mcp__canva__export_design'], serverNames);
    expect(defs[0].function.parameters).toEqual({ type: 'object', properties: {} });
  });
  it('includes camelCase tool names (does not drop NocoDB-style tools)', () => {
    const nocodb = [
      { serverId: 'nocodb', toolName: 'createRecords', description: 'c', inputSchema: null },
      { serverId: 'nocodb', toolName: 'updateRecords', description: 'u', inputSchema: null },
      { serverId: 'nocodb', toolName: 'aggregate', description: 'a', inputSchema: null },
    ];
    const defs = buildToolDefsFromCache(nocodb, ['mcp__nocodb__*'], new Map([['nocodb', 'NocoDB']]));
    expect(defs.map((d) => d.function.name)).toEqual([
      'mcp__nocodb__createRecords',
      'mcp__nocodb__updateRecords',
      'mcp__nocodb__aggregate',
    ]);
  });
});
