import { describe, test, expect } from 'bun:test';
import { StaleCleanupTask } from '../src/cleanup.js';
import { MemoryPrekeyStore } from '../src/memory-store.js';

function rand(n: number): Uint8Array {
  const buf = new Uint8Array(n);
  globalThis.crypto.getRandomValues(buf);
  return buf;
}

describe('StaleCleanupTask', () => {
  test('runs once immediately on start', async () => {
    const store = new MemoryPrekeyStore();
    // Save an untouched (so stale) identity
    await store.saveIdentity('ancient', rand(32), rand(32));

    const task = new StaleCleanupTask(store, { staleDays: 1, intervalHours: 24 });
    task.start();
    // Give the immediate run a microtask to complete
    await new Promise((r) => setTimeout(r, 50));

    expect(await store.getIdentity('ancient')).toBeNull();
    task.stop();
  });

  test('runOnce returns count of purged addresses', async () => {
    const store = new MemoryPrekeyStore();
    await store.saveIdentity('ancient1', rand(32), rand(32));
    await store.saveIdentity('ancient2', rand(32), rand(32));

    const task = new StaleCleanupTask(store, { staleDays: 1 });
    const count = await task.runOnce();
    expect(count).toBe(2);
  });

  test('leaves fresh identities alone', async () => {
    const store = new MemoryPrekeyStore();
    await store.saveIdentity('fresh', rand(32), rand(32));
    await store.touchIdentity('fresh');

    const task = new StaleCleanupTask(store, { staleDays: 30 });
    const count = await task.runOnce();
    expect(count).toBe(0);
    expect(await store.getIdentity('fresh')).not.toBeNull();
  });

  test('stop clears the interval', () => {
    const store = new MemoryPrekeyStore();
    const task = new StaleCleanupTask(store, { staleDays: 1, intervalHours: 1 });
    task.start();
    expect(task.isRunning).toBe(true);
    task.stop();
    expect(task.isRunning).toBe(false);
  });

  test('reads defaults from env vars', () => {
    const store = new MemoryPrekeyStore();
    const oldDays = process.env.SHADE_STALE_DAYS;
    const oldHours = process.env.SHADE_CLEANUP_INTERVAL_HOURS;
    process.env.SHADE_STALE_DAYS = '7';
    process.env.SHADE_CLEANUP_INTERVAL_HOURS = '12';
    try {
      const task = new StaleCleanupTask(store);
      // staleMs = 7 days, intervalMs = 12 hours
      expect((task as any).staleMs).toBe(7 * 24 * 60 * 60 * 1000);
      expect((task as any).intervalMs).toBe(12 * 60 * 60 * 1000);
    } finally {
      if (oldDays !== undefined) process.env.SHADE_STALE_DAYS = oldDays;
      else delete process.env.SHADE_STALE_DAYS;
      if (oldHours !== undefined) process.env.SHADE_CLEANUP_INTERVAL_HOURS = oldHours;
      else delete process.env.SHADE_CLEANUP_INTERVAL_HOURS;
    }
  });
});
