import { describe, expect, it, vi, beforeEach } from 'vitest';
import type { SessionHandle } from '../../../wasm/relicario_wasm';
import { clearCurrent, getCurrent, setCurrent } from '../session';

describe('session', () => {
  beforeEach(() => {
    // Reset module-scope `current` between tests. Overwrite first with a
    // benign no-throw fake so a prior test's throwing handle can't escape.
    setCurrent({ free: vi.fn(), value: 0 } as unknown as SessionHandle);
    clearCurrent();
  });

  it('clearCurrent() is a no-op when no handle is set', () => {
    expect(() => clearCurrent()).not.toThrow();
    expect(getCurrent()).toBeNull();
  });

  it('clearCurrent() calls free() exactly once and clears current', () => {
    const free = vi.fn();
    setCurrent({ free, value: 1 } as unknown as SessionHandle);

    clearCurrent();
    expect(free).toHaveBeenCalledTimes(1);
    expect(getCurrent()).toBeNull();

    clearCurrent();
    expect(free).toHaveBeenCalledTimes(1);
    expect(getCurrent()).toBeNull();
  });

  it('clearCurrent() propagates exceptions from free()', () => {
    const free = vi.fn(() => { throw new Error('boom'); });
    setCurrent({ free, value: 2 } as unknown as SessionHandle);

    expect(() => clearCurrent()).toThrow(/boom/);
  });
});
