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

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

describe('PrekeyStore cleanup API', () => {
  test('touchIdentity updates last activity', async () => {
    const store = new MemoryPrekeyStore();
    await store.saveIdentity('alice', rand(32), rand(32));
    await store.touchIdentity('alice');
    // Verify identity is still there
    expect(await store.getIdentity('alice')).not.toBeNull();
  });

  test('purgeStaleIdentities removes old addresses', async () => {
    const store = new MemoryPrekeyStore();

    // Alice was active long ago
    await store.saveIdentity('alice', rand(32), rand(32));
    await store.saveSignedPreKey('alice', 1, rand(32), rand(64));
    await store.saveOneTimePreKeys('alice', [{ keyId: 100, publicKey: rand(32) }]);
    // Manually set alice's activity to 1 day ago
    await store.touchIdentity('alice');
    (store as any).lastActivity.set('alice', Date.now() - 2 * 24 * 60 * 60 * 1000);

    // Bob is fresh
    await store.saveIdentity('bob', rand(32), rand(32));
    await store.touchIdentity('bob');

    // Purge anything older than 1 day
    const count = await store.purgeStaleIdentities(24 * 60 * 60 * 1000);
    expect(count).toBe(1);

    // Alice is gone
    expect(await store.getIdentity('alice')).toBeNull();
    expect(await store.getSignedPreKey('alice')).toBeNull();
    expect(await store.getOneTimePreKeyCount('alice')).toBe(0);

    // Bob is still there
    expect(await store.getIdentity('bob')).not.toBeNull();
  });

  test('purge returns 0 when nothing is stale', async () => {
    const store = new MemoryPrekeyStore();
    await store.saveIdentity('alice', rand(32), rand(32));
    await store.touchIdentity('alice');

    const count = await store.purgeStaleIdentities(60 * 60 * 1000); // 1 hour
    expect(count).toBe(0);
  });

  test('untouched identities are considered stale', async () => {
    const store = new MemoryPrekeyStore();
    // Save without touching — simulates an ancient identity from before cleanup API
    await store.saveIdentity('ancient', rand(32), rand(32));

    const count = await store.purgeStaleIdentities(1000);
    expect(count).toBe(1);
    expect(await store.getIdentity('ancient')).toBeNull();
  });
});
