import { describe, it, expect } from 'vitest';
import { runWithTrace, currentTraceId, toTraceparent, traceIdFromTraceparent, newTraceId } from './trace-context';

describe('trace context (P9 observability)', () => {
  it('currentTraceId reflects the active runWithTrace scope', () => {
    expect(currentTraceId()).toBeUndefined();
    runWithTrace('t1', () => {
      expect(currentTraceId()).toBe('t1');
    });
    expect(currentTraceId()).toBeUndefined();
  });

  it('isolates concurrent async contexts', async () => {
    const seen: Record<string, string | undefined> = {};
    await Promise.all([
      runWithTrace('a', async () => { await Promise.resolve(); seen.a = currentTraceId(); }),
      runWithTrace('b', async () => { await Promise.resolve(); seen.b = currentTraceId(); }),
    ]);
    expect(seen).toEqual({ a: 'a', b: 'b' });
  });

  it('toTraceparent is a valid W3C traceparent', () => {
    const tp = toTraceparent(newTraceId());
    expect(tp).toMatch(/^00-[0-9a-f]{32}-[0-9a-f]{16}-01$/);
  });

  it('traceIdFromTraceparent extracts the trace id field', () => {
    const tp = '00-0123456789abcdef0123456789abcdef-abcdef0123456789-01';
    expect(traceIdFromTraceparent(tp)).toBe('0123456789abcdef0123456789abcdef');
    expect(traceIdFromTraceparent(undefined)).toBeUndefined();
    expect(traceIdFromTraceparent('garbage')).toBeUndefined();
  });
});
