import { expect, tap } from '@git.zone/tstest/tapbundle';
import { OnvifMapper, type IOnvifSnapshot } from '../../ts/integrations/onvif/index.js';

const snapshot: IOnvifSnapshot = {
  id: 'front-door',
  name: 'Front Door',
  host: '192.168.1.60',
  port: 80,
  transport: 'http',
  connected: true,
  configured: true,
  cameras: [
    {
      id: 'front-door',
      name: 'Front Door',
      host: '192.168.1.60',
      port: 80,
      online: true,
      deviceInfo: {
        manufacturer: 'ExampleCam',
        model: 'IPC-4K',
        firmwareVersion: '1.2.3',
        serialNumber: 'FD1234',
        macAddress: 'AA:BB:CC:DD:EE:FF',
      },
      capabilities: {
        snapshot: true,
        stream: true,
        ptz: true,
        events: true,
      },
      profiles: [
        {
          index: 0,
          token: 'profile_1',
          name: 'Main',
          video: {
            encoding: 'H264',
            resolution: { width: 1920, height: 1080 },
          },
          streamUri: 'rtsp://192.168.1.60/stream1',
          snapshotUri: 'http://192.168.1.60/snapshot.jpg',
          ptz: {
            relative: true,
            presets: ['1'],
          },
        },
      ],
      streams: [
        {
          profileToken: 'profile_1',
          uri: 'rtsp://192.168.1.60/stream1',
          protocol: 'rtsp',
          encoding: 'H264',
          resolution: { width: 1920, height: 1080 },
        },
      ],
      events: [
        {
          uid: 'front_motion',
          name: 'Motion',
          platform: 'binary_sensor',
          deviceClass: 'motion',
          value: true,
        },
      ],
    },
  ],
};

tap.test('maps ONVIF cameras and profiles to canonical devices and constrained entities', async () => {
  const devices = OnvifMapper.toDevices(snapshot);
  const entities = OnvifMapper.toEntities(snapshot);

  expect(devices[0].id).toEqual('onvif.camera.aa_bb_cc_dd_ee_ff');
  expect(devices[0].features.some((featureArg) => featureArg.capability === 'camera')).toBeTrue();
  expect(entities.find((entityArg) => entityArg.id === 'sensor.front_door_main_camera')?.platform).toEqual('sensor');
  expect(entities.find((entityArg) => entityArg.id === 'sensor.front_door_main_camera')?.attributes?.capability).toEqual('camera');
  expect(entities.find((entityArg) => entityArg.id === 'binary_sensor.front_door_motion')?.state).toEqual('on');
});

tap.test('maps camera stream, snapshot, and PTZ services to ONVIF commands', async () => {
  const streamCommand = OnvifMapper.commandForService(snapshot, {
    domain: 'camera',
    service: 'stream_metadata',
    target: { entityId: 'sensor.front_door_main_camera' },
  });
  const snapshotCommand = OnvifMapper.commandForService(snapshot, {
    domain: 'camera',
    service: 'snapshot_metadata',
    target: { entityId: 'sensor.front_door_main_camera' },
  });
  const ptzCommand = OnvifMapper.commandForService(snapshot, {
    domain: 'camera',
    service: 'ptz',
    target: { entityId: 'sensor.front_door_main_camera' },
    data: { move_mode: 'RelativeMove', pan: 'LEFT', distance: 0.1 },
  });

  expect(streamCommand?.type).toEqual('stream_metadata');
  expect(snapshotCommand?.type).toEqual('snapshot_metadata');
  expect(ptzCommand?.ptz?.moveMode).toEqual('RelativeMove');
  expect(ptzCommand?.ptz?.pan).toEqual('LEFT');
});

export default tap.start();
