/**
 * OpenAPI Schema Parser
 */

import type { TypeRegistry } from '../types/index.js'
import type { TypeDescriptor } from '../types/type-descriptor.js'

export class OpenAPIParser {
  parse(schema: any): TypeRegistry {
    const types: TypeRegistry = {}
    
    if (!schema.paths) return types
    
    for (const [path, pathObj] of Object.entries(schema.paths as any)) {
      for (const [method, methodObj] of Object.entries(pathObj as any)) {
        if (typeof methodObj !== 'object' || !methodObj) continue
        
        const endpoint = `${method.toUpperCase()} ${path}`
        const responses = (methodObj as any).responses || {}
        const requestBody = (methodObj as any).requestBody
        
        // Extract response type from schema
        const responseSchema = responses['200']?.content?.['application/json']?.schema
        const requestSchema = requestBody?.content?.['application/json']?.schema
        
        types[endpoint] = {
          request: this.schemaToType(requestSchema),
          response: this.schemaToType(responseSchema),
          method: method.toUpperCase(),
          lastSeen: Date.now(),
          samples: []
        }
      }
    }
    
    return types
  }
  
  private schemaToType(schema: any): TypeDescriptor {
    if (!schema) return { type: 'unknown' }
    
    switch (schema.type) {
      case 'string':
        return { type: 'string' }
      case 'number':
      case 'integer':
        return { type: 'number' }
      case 'boolean':
        return { type: 'boolean' }
      case 'null':
        return { type: 'null' }
      case 'array':
        return { 
          type: 'array', 
          items: schema.items ? this.schemaToType(schema.items) : { type: 'unknown' }
        }
      case 'object':
        if (!schema.properties) {
          return { type: 'object', properties: {} }
        }
        
        const properties: Record<string, TypeDescriptor> = {}
        const required: string[] = schema.required || []
        
        for (const [key, prop] of Object.entries(schema.properties)) {
          properties[key] = this.schemaToType(prop)
        }
        
        return { type: 'object', properties, required }
      default:
        // Handle oneOf, anyOf, allOf
        if (schema.oneOf || schema.anyOf) {
          const schemas = schema.oneOf || schema.anyOf
          const types = schemas.map((s: any) => this.schemaToType(s))
          return { type: 'union', types }
        }
        
        return { type: 'unknown' }
    }
  }
}