import { expect, tap } from '@git.zone/tstest/tapbundle';
import { Go2rtcMapper, type IGo2rtcConfig, type IGo2rtcSnapshot } from '../../ts/integrations/go2rtc/index.js';

const config: IGo2rtcConfig = {
  url: 'http://192.168.1.20:1984',
  name: 'Video Router',
  uniqueId: 'video-router',
  serverInfo: {
    version: '1.9.14',
    host: '192.168.1.20:1984',
    rtsp: { listen: ':8554', defaultQuery: 'video&audio' },
  },
  schemes: ['rtsp', 'ffmpeg', 'webrtc'],
  streams: [{
    id: 'front_door',
    name: 'front_door',
    sourceUrls: ['rtsp://camera.local/stream1'],
    producerCount: 1,
    consumerCount: 1,
    producers: [{ url: 'rtsp://camera.local/stream1', tracks: [{ kind: 'video', codec: 'h264' }, { kind: 'audio', codec: 'opus' }] }],
    consumers: [{ url: 'webrtc:ws://192.168.1.20:1984/api/ws?src=front_door' }],
    online: true,
    configured: true,
  }],
};

tap.test('maps go2rtc streams to cameras, endpoints, and status sensors', async () => {
  const snapshot = Go2rtcMapper.toSnapshot(config, true, 'manual');
  const devices = Go2rtcMapper.toDevices(snapshot);
  const entities = Go2rtcMapper.toEntities(snapshot);
  const camera = entities.find((entityArg) => entityArg.id === 'camera.front_door');

  expect(snapshot.cameras[0].endpoints.snapshotUrl).toEqual('http://192.168.1.20:1984/api/frame.jpeg?src=front_door');
  expect(snapshot.cameras[0].endpoints.whepUrl).toEqual('http://192.168.1.20:1984/api/webrtc?src=front_door');
  expect(snapshot.cameras[0].endpoints.websocketUrl).toEqual('ws://192.168.1.20:1984/api/ws?src=front_door');
  expect(snapshot.cameras[0].endpoints.rtspUrl).toEqual('rtsp://192.168.1.20:8554/front_door?video&audio');
  expect(devices[0].features.some((featureArg) => featureArg.capability === 'camera')).toBeTrue();
  expect(camera?.attributes?.streamSource).toEqual('rtsp://192.168.1.20:8554/front_door?video&audio');
  expect(camera?.attributes?.webRtcUrl).toEqual('http://192.168.1.20:1984/api/webrtc?src=front_door');
  expect(entities.find((entityArg) => entityArg.id === 'sensor.front_door_status')?.state).toEqual('streaming');
  expect(entities.find((entityArg) => entityArg.id === 'sensor.front_door_producers')?.state).toEqual(1);
});

tap.test('maps camera and go2rtc services to safe native commands', async () => {
  const snapshot: IGo2rtcSnapshot = Go2rtcMapper.toSnapshot(config, true, 'manual');
  const streamCommand = Go2rtcMapper.commandForService(snapshot, {
    domain: 'camera',
    service: 'stream_source',
    target: { entityId: 'camera.front_door' },
    data: { endpoint: 'webrtc' },
  });
  const snapshotCommand = Go2rtcMapper.commandForService(snapshot, {
    domain: 'camera',
    service: 'snapshot',
    target: { entityId: 'camera.front_door' },
    data: { width: '640', height: 360 },
  });
  const addCommand = Go2rtcMapper.commandForService(snapshot, {
    domain: 'go2rtc',
    service: 'add_stream',
    target: {},
    data: { name: 'garage', src: 'rtsp://camera.local/garage' },
  });
  const reloadCommand = Go2rtcMapper.commandForService(snapshot, {
    domain: 'go2rtc',
    service: 'reload',
    target: {},
  });
  const streamToCameraCommand = Go2rtcMapper.commandForService(snapshot, {
    domain: 'go2rtc',
    service: 'stream_to_camera',
    target: { entityId: 'camera.front_door' },
    data: { src: 'ffmpeg:http://example.test/doorbell.mp3#audio=pcma#input=file' },
  });

  expect(streamCommand?.type).toEqual('stream_source');
  expect(streamCommand?.streamSource?.endpoint).toEqual('whepUrl');
  expect(snapshotCommand?.type).toEqual('snapshot_image');
  expect(snapshotCommand?.snapshot?.width).toEqual(640);
  expect(snapshotCommand?.snapshot?.height).toEqual(360);
  expect(addCommand?.httpCommands?.[0]).toEqual({ label: 'add_stream', method: 'PUT', path: '/api/streams', query: { name: 'garage', src: 'rtsp://camera.local/garage' }, expect: 'empty' });
  expect(reloadCommand?.httpCommands?.[0].path).toEqual('/api/restart');
  expect(streamToCameraCommand?.streamMutation?.dst).toEqual('front_door');
});

export default tap.start();
