import { it, expect, vi } from 'vitest'
import { createRedisBackend } from './redis.js'

function createFakeRedis() {
  const store = new Map<string, { value: string; ex?: number }>()
  return {
    store,
    async get(key: string) {
      return store.get(key)?.value ?? null
    },
    async set(key: string, value: string, mode?: 'EX', ttl?: number) {
      if (mode === 'EX') {
        store.set(key, { value, ex: ttl })
        return 'OK'
      }
      store.set(key, { value })
      return 'OK'
    },
    async del(key: string) {
      return store.delete(key) ? 1 : 0
    },
  }
}

it('redis.get null → undefined', async () => {
  const backend = createRedisBackend(createFakeRedis() as never)
  await expect(backend.get('missing')).resolves.toBeUndefined()
})

it('set + get round-trip without ttl', async () => {
  const redis = createFakeRedis()
  const set = vi.spyOn(redis, 'set')
  const backend = createRedisBackend(redis as never)
  await backend.set('k', 'v')
  expect(set).toHaveBeenCalledWith('k', 'v')
  await expect(backend.get('k')).resolves.toBe('v')
})

it('ttl → client.set with EX', async () => {
  const redis = createFakeRedis()
  const set = vi.spyOn(redis, 'set')
  const backend = createRedisBackend(redis as never)
  await backend.set('k', 'v', 60)
  expect(set).toHaveBeenCalledWith('k', 'v', 'EX', 60)
})

it('del → client.del', async () => {
  const redis = createFakeRedis()
  const del = vi.spyOn(redis, 'del')
  const backend = createRedisBackend(redis as never)
  await backend.del('k')
  expect(del).toHaveBeenCalledWith('k')
})
