const { logToFile } = require('./logger');

class MemoryCache {
  constructor() {
    this.store = new Map();
  }

  get(key) {
    const entry = this.store.get(key);
    if (!entry) return null;
    if (Date.now() > entry.expiresAt) {
      this.store.delete(key);
      return null;
    }
    return entry.value;
  }

  set(key, value, ttlMs) {
    this.store.set(key, {
      value,
      expiresAt: Date.now() + ttlMs
    });
  }

  invalidate(key) {
    this.store.delete(key);
  }

  clear() {
    this.store.clear();
  }

  getStats() {
    const now = Date.now();
    const entries = [];
    let totalSize = 0;

    for (const [key, entry] of this.store.entries()) {
      // Maps must be converted before JSON.stringify (which renders them as "{}")
      const serializable = entry.value instanceof Map ? Object.fromEntries(entry.value) : entry.value;
      const json = JSON.stringify(serializable);
      const sizeBytes = Buffer.byteLength(json, 'utf8');
      totalSize += sizeBytes;
      const ttlRemaining = Math.max(0, entry.expiresAt - now);
      const expired = now > entry.expiresAt;
      let itemCount = null;
      if (entry.value instanceof Map) {
        itemCount = entry.value.size;
      } else if (Array.isArray(entry.value)) {
        itemCount = entry.value.length;
      } else if (entry.value && typeof entry.value === 'object') {
        if (Array.isArray(entry.value.records)) itemCount = entry.value.records.length;
        else if (Array.isArray(entry.value.slots)) itemCount = entry.value.slots.length;
      }
      entries.push({
        key,
        sizeBytes,
        itemCount,
        ttlRemainingMs: ttlRemaining,
        expired
      });
    }

    return {
      entryCount: this.store.size,
      totalSizeBytes: totalSize,
      entries
    };
  }
}

const cache = new MemoryCache();

module.exports = cache;
