/**
 * @fileoverview Tests for tool registry to improve code coverage
 */

import { describe, it, expect } from 'vitest';
import { ToolRegistry } from '../../server/tool-registry.js';

// Type for accessing private static methods in tests
type ToolRegistryStatic = typeof ToolRegistry & {
  matchesPattern: (filename: string, patterns: string[]) => boolean;
  passesFilters: (
    tool: { metadata?: { category?: string; tags?: string[] } },
    options: {
      includeCategories?: string[];
      excludeCategories?: string[];
      includeTags?: string[];
      excludeTags?: string[];
    }
  ) => boolean;
};

describe('ToolRegistry - Coverage Tests', () => {
  // These tests only test static methods, so no setup is needed

  describe('Static helper methods', () => {
    it('matchesPattern should correctly match file patterns', () => {
      const matchesPattern = (ToolRegistry as unknown as ToolRegistryStatic).matchesPattern;

      // Test exact match
      expect(matchesPattern('test.js', ['test.js'])).toBe(true);
      expect(matchesPattern('test.js', ['other.js'])).toBe(false);

      // Test wildcard patterns
      expect(matchesPattern('test.tool.js', ['*.tool.js'])).toBe(true);
      expect(matchesPattern('test.js', ['*.tool.js'])).toBe(false);

      // Test multiple patterns
      expect(matchesPattern('test.js', ['*.js', '*.ts'])).toBe(true);
      expect(matchesPattern('test.py', ['*.js', '*.ts'])).toBe(false);

      // Test edge cases
      expect(matchesPattern('', [''])).toBe(true);
      expect(matchesPattern('file', ['*'])).toBe(true);
    });

    it('passesFilters should handle various filter combinations', () => {
      const passesFilters = (ToolRegistry as unknown as ToolRegistryStatic).passesFilters;

      // Tool with full metadata
      const tool = {
        name: 'test-tool',
        description: 'Test tool',
        handler: vi.fn(),
        metadata: {
          category: 'data',
          tags: ['stable', 'production'],
        },
      };

      // No filters - should pass
      expect(passesFilters(tool, {})).toBe(true);

      // Include category match
      expect(passesFilters(tool, { includeCategories: ['data'] })).toBe(true);
      expect(passesFilters(tool, { includeCategories: ['api'] })).toBe(false);

      // Exclude category
      expect(passesFilters(tool, { excludeCategories: ['data'] })).toBe(false);
      expect(passesFilters(tool, { excludeCategories: ['api'] })).toBe(true);

      // Include tags
      expect(passesFilters(tool, { includeTags: ['stable'] })).toBe(true);
      expect(passesFilters(tool, { includeTags: ['beta'] })).toBe(false);

      // Exclude tags
      expect(passesFilters(tool, { excludeTags: ['stable'] })).toBe(false);
      expect(passesFilters(tool, { excludeTags: ['beta'] })).toBe(true);

      // Combined filters
      expect(
        passesFilters(tool, {
          includeCategories: ['data'],
          includeTags: ['stable'],
        })
      ).toBe(true);

      // Tool without metadata
      const minimalTool = {
        name: 'minimal',
        description: 'Minimal tool',
        handler: vi.fn(),
      };

      expect(passesFilters(minimalTool, {})).toBe(true);
      expect(passesFilters(minimalTool, { includeCategories: ['any'] })).toBe(false);
      expect(passesFilters(minimalTool, { excludeCategories: ['any'] })).toBe(true);
    });
  });

  describe('Tool discovery helpers', () => {
    it('should handle empty patterns array', () => {
      const matchesPattern = (ToolRegistry as unknown as ToolRegistryStatic).matchesPattern;
      expect(matchesPattern('file.js', [])).toBe(false);
    });

    it('should handle patterns with special characters', () => {
      const matchesPattern = (ToolRegistry as unknown as ToolRegistryStatic).matchesPattern;

      // Pattern with dots
      expect(matchesPattern('test.min.js', ['*.min.js'])).toBe(true);

      // Pattern with dashes
      expect(matchesPattern('test-tool.js', ['*-tool.js'])).toBe(true);

      // Pattern with brackets (should be escaped)
      expect(matchesPattern('[test].js', ['[test].js'])).toBe(true);
      expect(matchesPattern('t.js', ['[test].js'])).toBe(false);
    });
  });

  describe('Filter edge cases', () => {
    it('should handle tools with partial metadata', () => {
      const passesFilters = (ToolRegistry as unknown as ToolRegistryStatic).passesFilters;

      const toolWithCategory = {
        name: 'tool',
        description: 'Tool',
        handler: vi.fn(),
        metadata: {
          category: 'data',
          // No tags
        },
      };

      expect(passesFilters(toolWithCategory, { includeTags: ['any'] })).toBe(false);
      expect(passesFilters(toolWithCategory, { excludeTags: ['any'] })).toBe(true);

      const toolWithTags = {
        name: 'tool',
        description: 'Tool',
        handler: vi.fn(),
        metadata: {
          // No category
          tags: ['beta'],
        },
      };

      expect(passesFilters(toolWithTags, { includeCategories: ['any'] })).toBe(false);
      expect(passesFilters(toolWithTags, { excludeCategories: ['any'] })).toBe(true);
    });

    it('should handle empty metadata object', () => {
      const passesFilters = (ToolRegistry as unknown as ToolRegistryStatic).passesFilters;

      const tool = {
        name: 'tool',
        description: 'Tool',
        handler: vi.fn(),
        metadata: {},
      };

      expect(passesFilters(tool, { includeCategories: ['any'] })).toBe(false);
      expect(passesFilters(tool, { includeTags: ['any'] })).toBe(false);
      expect(passesFilters(tool, { excludeCategories: ['any'] })).toBe(true);
      expect(passesFilters(tool, { excludeTags: ['any'] })).toBe(true);
    });

    it('should handle filters with empty arrays', () => {
      const passesFilters = (ToolRegistry as unknown as ToolRegistryStatic).passesFilters;

      const tool = {
        name: 'tool',
        description: 'Tool',
        handler: vi.fn(),
        metadata: {
          category: 'data',
          tags: ['stable'],
        },
      };

      // Empty filter arrays should not filter anything
      expect(passesFilters(tool, { includeCategories: [] })).toBe(true);
      expect(passesFilters(tool, { excludeCategories: [] })).toBe(true);
      expect(passesFilters(tool, { includeTags: [] })).toBe(true);
      expect(passesFilters(tool, { excludeTags: [] })).toBe(true);
    });

    it('should handle multiple tag matching', () => {
      const passesFilters = (ToolRegistry as unknown as ToolRegistryStatic).passesFilters;

      const tool = {
        name: 'tool',
        description: 'Tool',
        handler: vi.fn(),
        metadata: {
          tags: ['alpha', 'beta', 'experimental'],
        },
      };

      // Should pass if ANY include tag matches
      expect(passesFilters(tool, { includeTags: ['beta', 'stable'] })).toBe(true);
      expect(passesFilters(tool, { includeTags: ['stable', 'production'] })).toBe(false);

      // Should fail if ANY exclude tag matches
      expect(passesFilters(tool, { excludeTags: ['beta', 'stable'] })).toBe(false);
      expect(passesFilters(tool, { excludeTags: ['stable', 'production'] })).toBe(true);
    });
  });
});
