import { describe, it, expect } from 'vitest';
import { promises as fs } from 'fs';
import path from 'path';

interface Tool {
  name: string;
  description: string;
  inputSchema?: {
    type: string;
    properties?: Record<string, any>;
    required?: string[];
  };
}

describe('Tool Schema Validation', () => {
  it('should have required field for all tools with properties in inputSchema', async () => {
    const toolsWithMissingRequired: Array<{ file: string; tool: string; line?: number }> = [];

    // Read all module files and find tool definitions
    const modulesDir = path.join(process.cwd(), 'src/modules');
    const moduleFiles = await fs.readdir(modulesDir, { recursive: true });
    
    for (const file of moduleFiles) {
      if (typeof file === 'string' && file.endsWith('index.ts') && !file.includes('__tests__')) {
        const filePath = path.join(modulesDir, file);
        const content = await fs.readFile(filePath, 'utf-8');
        const lines = content.split('\n');
        
        // Find tool definitions
        for (let i = 0; i < lines.length; i++) {
          const line = lines[i];
          
          // Look for tool definitions
          if (line.includes('name:') && line.includes("'") && i > 0 && lines[i-1].includes('{')) {
            const toolNameMatch = line.match(/name:\s*['"]([^'"]+)['"]/);
            if (toolNameMatch) {
              const toolName = toolNameMatch[1];
              
              // Look for inputSchema
              let j = i + 1;
              let hasInputSchema = false;
              let hasProperties = false;
              let hasRequired = false;
              let braceCount = 1;
              
              while (j < lines.length && braceCount > 0) {
                const currentLine = lines[j];
                
                if (currentLine.includes('inputSchema:')) {
                  hasInputSchema = true;
                }
                
                if (hasInputSchema && currentLine.includes('properties:')) {
                  hasProperties = true;
                }
                
                if (hasInputSchema && currentLine.includes('required:')) {
                  hasRequired = true;
                }
                
                // Count braces to know when tool definition ends
                braceCount += (currentLine.match(/\{/g) || []).length;
                braceCount -= (currentLine.match(/\}/g) || []).length;
                
                j++;
              }
              
              if (hasInputSchema && hasProperties && !hasRequired) {
                toolsWithMissingRequired.push({
                  file: file,
                  tool: toolName,
                  line: i + 1
                });
              }
            }
          }
        }
      }
    }

    // This test should fail initially, showing which tools are missing the required field
    if (toolsWithMissingRequired.length > 0) {
      console.log('\nTools missing required field:');
      toolsWithMissingRequired.forEach(({ file, tool, line }) => {
        console.log(`  - ${file}: ${tool} (line ~${line})`);
      });
    }

    expect(toolsWithMissingRequired).toHaveLength(0);
  });

  it('should be able to reproduce the JSON Schema validation error', () => {
    // Example of a schema that would fail validation
    const invalidSchema = {
      type: 'object',
      properties: {
        name: { type: 'string' },
        age: { type: 'number' }
      }
      // Missing required field
    };

    const validSchema = {
      type: 'object',
      properties: {
        name: { type: 'string' },
        age: { type: 'number' }
      },
      required: [] // Even empty array is valid
    };

    // This demonstrates the issue - schemas with properties should have required field
    expect(invalidSchema).not.toHaveProperty('required');
    expect(validSchema).toHaveProperty('required');
  });
});