// Redis Cache Adapter — Upstash REST API
// Uses the Upstash Redis REST API (HTTP-based, no Redis client package needed).
// Values are JSON-serialized strings. Errors are silenced — falls back to null on any failure.
// TTL is specified in milliseconds (stored via PX flag).

import type { CacheAdapter } from './adapter'

export class RedisAdapter implements CacheAdapter {
  private readonly url: string
  private readonly token: string

  constructor(url: string, token: string) {
    // Normalize: strip trailing slash
    this.url = url.replace(/\/$/, '')
    this.token = token
  }

  private async command<T>(cmd: unknown[]): Promise<T | null> {
    try {
      const res = await fetch(this.url, {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${this.token}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(cmd),
      })
      if (!res.ok) return null
      const body = await res.json() as { result: T | null }
      return body.result
    } catch {
      // Network error, auth failure, etc. — treat as cache miss.
      return null
    }
  }

  async get<T>(key: string): Promise<T | null> {
    const raw = await this.command<string>(['GET', key])
    if (raw === null || raw === undefined) return null
    try {
      return JSON.parse(raw) as T
    } catch {
      // Corrupted value — treat as miss
      return null
    }
  }

  async set<T>(key: string, value: T, ttlMs: number): Promise<void> {
    await this.command(['SET', key, JSON.stringify(value), 'PX', ttlMs])
  }

  async delete(key: string): Promise<void> {
    await this.command(['DEL', key])
  }
}
