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

import { verifyTerminalToken } from '../../src/terminal-token';

const mint = (jobId: string, expiresAt: number, secret: string) => {
  const payload = `${expiresAt}.${jobId}`;
  const sig = createHmac('sha256', secret).update(payload).digest('hex');
  return `${payload}.${sig}`;
};

describe('verifyTerminalToken', () => {
  const secret = 'test-secret';

  test('accepts a valid, unexpired, job-matched token', () => {
    const token = mint('job1', Date.now() + 60_000, secret);
    expect(verifyTerminalToken(token, 'job1', secret)).toBe(true);
  });

  test('rejects an expired token', () => {
    const token = mint('job1', Date.now() - 1, secret);
    expect(verifyTerminalToken(token, 'job1', secret)).toBe(false);
  });

  test('rejects a token minted for another job', () => {
    const token = mint('job1', Date.now() + 60_000, secret);
    expect(verifyTerminalToken(token, 'job2', secret)).toBe(false);
  });

  test('rejects a token signed with a different secret', () => {
    const token = mint('job1', Date.now() + 60_000, 'other-secret');
    expect(verifyTerminalToken(token, 'job1', secret)).toBe(false);
  });

  test('rejects malformed input and an empty secret', () => {
    expect(verifyTerminalToken('garbage', 'job1', secret)).toBe(false);
    expect(verifyTerminalToken('', 'job1', secret)).toBe(false);
    expect(
      verifyTerminalToken(mint('job1', Date.now() + 1000, ''), 'job1', ''),
    ).toBe(false);
  });
});
