import { createHmac } from 'node:crypto';
import { describe, expect, it } from 'vitest';

import { buildBoxToken } from '../../src/lib/box-terminal-token';

describe('buildBoxToken', () => {
  const secret = 'test-secret';
  const wsBase = 'wss://worker.example.com';
  const username = 'alice';
  const now = 1_700_000_000_000;

  it('returns null when the secret is unset', () => {
    expect(buildBoxToken(username, undefined, wsBase, now)).toBeNull();
  });

  it('returns null when the WS base is unset', () => {
    expect(buildBoxToken(username, secret, undefined, now)).toBeNull();
  });

  it('mints a 4-part box token matching the worker format', () => {
    const result = buildBoxToken(username, secret, wsBase, now);
    expect(result).not.toBeNull();
    const { url, expiresAt } = result!;

    expect(expiresAt).toBe(now + 2 * 60 * 1000);

    const expectedHmac = createHmac('sha256', secret)
      .update(`${expiresAt}.box.${username}`)
      .digest('hex');
    const expectedToken = `${expiresAt}.box.${username}.${expectedHmac}`;

    expect(url).toContain('/box/terminal?token=');
    expect(url).toBe(
      `${wsBase}/box/terminal?token=${encodeURIComponent(expectedToken)}`,
    );

    const token = decodeURIComponent(new URL(url).searchParams.get('token')!);
    expect(token).toBe(expectedToken);
    const parts = token.split('.');
    expect(parts).toHaveLength(4);
    expect(parts[1]).toBe('box');
    expect(parts[2]).toBe(username);
  });

  it('strips a trailing slash from the WS base', () => {
    const result = buildBoxToken(username, secret, `${wsBase}/`, now);
    expect(result!.url.startsWith(`${wsBase}/box/terminal?token=`)).toBe(true);
  });
});
