import { createHash } from 'crypto';
import type { RegistryServer, SearchOptions } from './types.js';

export class RegistryCache {
  private cache = new Map<string, { data: RegistryServer[]; expires: number }>();
  private defaultTTL: number;
  private hits = 0;
  private misses = 0;

  constructor(ttlMs = 3_600_000) {
    this.defaultTTL = ttlMs;
  }

  private getKey(query: string, options: SearchOptions): string {
    return createHash('sha256')
      .update(JSON.stringify({ query, options }))
      .digest('hex');
  }

  get(query: string, options: SearchOptions): RegistryServer[] | null {
    const key = this.getKey(query, options);
    const entry = this.cache.get(key);
    if (entry !== undefined && entry.expires > Date.now()) {
      this.hits++;
      return entry.data;
    }
    if (entry !== undefined) {
      this.cache.delete(key);
    }
    this.misses++;
    return null;
  }

  set(query: string, options: SearchOptions, data: RegistryServer[]): void {
    const key = this.getKey(query, options);
    this.cache.set(key, { data, expires: Date.now() + this.defaultTTL });
  }

  getHitRatio(): { hits: number; misses: number; ratio: number } {
    const total = this.hits + this.misses;
    return {
      hits: this.hits,
      misses: this.misses,
      ratio: total === 0 ? 0 : this.hits / total,
    };
  }

  clear(): void {
    this.cache.clear();
    this.hits = 0;
    this.misses = 0;
  }

  get size(): number {
    return this.cache.size;
  }
}
