/**
 * W-TinyLFU Cache Implementation
 * Advanced caching with frequency-based eviction
 */

export class WTinyLFUCache<T = unknown> {
  private cache = new Map<string, { data: T; expires: number; frequency: number }>()
  private frequencies = new Map<string, number>()
  private maxSize: number
  private accessCount = 0
  
  constructor(maxSize = 1000) {
    this.maxSize = maxSize
  }
  
  get(key: string): T | null {
    this.accessCount++
    const item = this.cache.get(key)
    
    if (!item) {
      this.frequencies.set(key, (this.frequencies.get(key) || 0) + 1)
      return null
    }
    
    if (Date.now() > item.expires) {
      this.cache.delete(key)
      return null
    }
    
    item.frequency++
    this.frequencies.set(key, (this.frequencies.get(key) || 0) + 1)
    return item.data
  }
  
  set(key: string, data: T, ttl = 300000): void {
    const expires = Date.now() + ttl
    const frequency = this.frequencies.get(key) || 0
    
    if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
      this.evictLFU()
    }
    
    this.cache.set(key, { data, expires, frequency })
    this.frequencies.set(key, frequency + 1)
  }
  
  private evictLFU(): void {
    let minFreq = Infinity
    let lruKey = ''
    
    for (const [key, item] of this.cache) {
      const freq = this.frequencies.get(key) || 0
      if (freq < minFreq) {
        minFreq = freq
        lruKey = key
      }
    }
    
    if (lruKey) {
      this.cache.delete(lruKey)
      this.frequencies.delete(lruKey)
    }
  }
  
  clear(): void {
    this.cache.clear()
    this.frequencies.clear()
  }
}