import { CacheAdapter } from './CacheAdapter.js'
import { MemoryCacheAdapter } from './MemoryCacheAdapter.js'
import { RedisCacheAdapter } from './RedisCacheAdapter.js'

/**
 * 缓存工厂类
 * 
 * 根据环境变量自动选择缓存实现：
 * - CACHE_TYPE=memory: 使用MemoryCacheAdapter（内存缓存）
 * - CACHE_TYPE=redis: 使用RedisCacheAdapter（Redis缓存）
 * 
 * 零代码切换：
 * - 本地开发：不配置CACHE_TYPE，默认使用memory
 * - 云端部署：配置CACHE_TYPE=redis，自动切换到Redis
 * 
 * @example
 * ```typescript
 * import { cache } from '@/common/cache'
 * 
 * // 业务代码不关心是memory还是redis
 * await cache.set('user:123', userData, 60)
 * const user = await cache.get('user:123')
 * ```
 */
export class CacheFactory {
  private static instance: CacheAdapter | null = null

  /**
   * 获取缓存适配器实例（单例模式）
   */
  static getInstance(): CacheAdapter {
    if (!this.instance) {
      this.instance = this.createAdapter()
    }
    return this.instance
  }

  /**
   * 创建缓存适配器
   */
  private static createAdapter(): CacheAdapter {
    const cacheType = process.env.CACHE_TYPE || 'memory'

    switch (cacheType) {
      case 'memory':
        return this.createMemoryAdapter()
      
      case 'redis':
        return this.createRedisAdapter()
      
      default:
        console.warn(`[CacheFactory] Unknown CACHE_TYPE: ${cacheType}, fallback to memory`)
        return this.createMemoryAdapter()
    }
  }

  /**
   * 创建内存缓存适配器
   */
  private static createMemoryAdapter(): MemoryCacheAdapter {
    console.log('[CacheFactory] Using MemoryCacheAdapter')
    return new MemoryCacheAdapter()
  }

  /**
   * 创建Redis缓存适配器
   */
  private static createRedisAdapter(): RedisCacheAdapter {
    const host = process.env.REDIS_HOST
    const port = parseInt(process.env.REDIS_PORT || '6379', 10)
    const password = process.env.REDIS_PASSWORD
    const db = parseInt(process.env.REDIS_DB || '0', 10)

    // 验证必需的环境变量
    if (!host) {
      throw new Error(
        '[CacheFactory] Redis configuration incomplete. REDIS_HOST is required when CACHE_TYPE=redis'
      )
    }

    console.log(`[CacheFactory] Using RedisCacheAdapter (host: ${host}:${port}, db: ${db})`)

    return new RedisCacheAdapter({
      host,
      port,
      password,
      db,
      keyPrefix: 'aiclinical:'
    })
  }

  /**
   * 重置实例（用于测试）
   */
  static reset(): void {
    this.instance = null
  }
}

