import { describe, expect, test } from 'bun:test';

import { NoopSfuService } from '../media/sfu/noop';

const buildInput = () => ({
  streamSessionId: 'stream-1',
  ownerUserId: 'user-1',
  cameraDeviceId: 'camera-1',
  requesterDeviceId: 'client-1',
});

describe('noop SFU service', () => {
  test('starts a session in starting state', async () => {
    const service = new NoopSfuService();

    const session = await service.startSession(buildInput());

    expect(session.streamSessionId).toBe('stream-1');
    expect(session.state).toBe('starting');
  });

  test('returns the existing session when startSession is called twice', async () => {
    const service = new NoopSfuService();

    const first = await service.startSession(buildInput());
    const second = await service.startSession(buildInput());

    expect(second).toEqual(first);
  });

  test('updates session state through the lifecycle and can read it back', async () => {
    const service = new NoopSfuService();
    await service.startSession(buildInput());
    await service.setSessionState('stream-1', 'live');

    expect(await service.getSession('stream-1')).toEqual({
      ...buildInput(),
      state: 'live',
      createdAt: expect.any(String),
    });
  });

  test('marks sessions as ended when endSession is called', async () => {
    const service = new NoopSfuService();
    await service.startSession(buildInput());
    await service.endSession('stream-1');

    expect((await service.getSession('stream-1'))?.state).toBe('ended');
  });

  test('creates publish and subscribe transports with generated ids', async () => {
    const service = new NoopSfuService();

    const publish = await service.createPublishTransport({
      streamSessionId: 'stream-1',
      cameraDeviceId: 'camera-1',
    });
    const subscribe = await service.createSubscribeTransport({
      streamSessionId: 'stream-1',
      viewerDeviceId: 'client-1',
    });

    expect(publish.transportId.startsWith('pub_')).toBe(true);
    expect(subscribe.transportId.startsWith('sub_')).toBe(true);
    expect(Array.isArray(publish.iceServers)).toBe(true);
    expect(Array.isArray(subscribe.iceServers)).toBe(true);
  });
});
