import { expect, tap } from '@git.zone/tstest/tapbundle';
import { FreeboxMapper, type IFreeboxRawData } from '../../ts/integrations/freebox/index.js';

export const freeboxRawData: Partial<IFreeboxRawData> = {
  apiVersionInfo: { uid: 'freebox-uid', device_name: 'Freebox Server', api_version: '6.0', api_base_url: '/api/', device_type: 'FreeboxServer1,2' },
  systemConfig: {
    mac: 'F4:CA:E5:5C:EA:14',
    serial: '805400T144100853',
    firmware_version: '4.8.0',
    board_name: 'fbxgw1r',
    uptime_val: 3600,
    model_info: { pretty_name: 'Freebox Server', name: 'fbxgw1r' },
    sensors: [{ name: 'CPU', value: 55 }],
  },
  connectionStatus: { rate_down: 1234, rate_up: 321, bandwidth_down: 1000000000, media: 'ftth', state: 'up', ipv4: '203.0.113.10' },
  callLog: [
    { id: 1, type: 'missed', datetime: 1700000000, name: 'Alice', number: '0102030405', new: true },
    { id: 2, type: 'outgoing', datetime: 1700000100, name: 'Bob', number: '0102030406', new: false },
  ],
  disks: [{ id: 1, model: 'Hitachi', serial: 'DISK123', firmware: 'PB2I', type: 'internal', state: 'enabled', temp: 42, partitions: [{ id: 3, disk_id: 1, label: 'Disque dur', state: 'mounted', fstype: 'ext4', total_bytes: 1000, free_bytes: 250, used_bytes: 750 }] }],
  raids: [{ id: 7, name: 'main', degraded: true }],
  lanHosts: [{ id: 'ether-aa:bb:cc:dd:ee:ff', primary_name: 'Phone', host_type: 'smartphone', vendor_name: 'Example', active: true, reachable: true, l2ident: { id: 'AA:BB:CC:DD:EE:FF' }, l3connectivities: [{ addr: '192.168.1.20', af: 'ipv4', active: true }] }],
  wifiConfig: { enabled: true, mac_filter_state: 'disabled' },
  homeNodes: [
    { id: 10, label: 'Hall Motion', category: 'pir', status: 'active', props: { FwVersion: '1.0' }, type: { endpoints: [{ id: 100, ep_type: 'signal', name: 'trigger' }] }, show_endpoints: [{ ep_type: 'signal', name: 'trigger', value: false }, { ep_type: 'signal', name: 'battery', value: 91 }] },
    { id: 11, label: 'Home Alarm', category: 'alarm', status: 'active', props: {}, type: { endpoints: [{ id: 200, ep_type: 'slot', name: 'alarm1' }, { id: 201, ep_type: 'slot', name: 'off' }, { id: 202, ep_type: 'signal', name: 'state' }] }, show_endpoints: [{ ep_type: 'signal', name: 'state', value: 'idle' }] },
    { id: 12, label: 'Front Camera', category: 'camera', status: 'active', props: { Stream: 'rtsp://camera/stream' }, type: { endpoints: [{ id: 300, ep_type: 'slot', name: 'detection' }] }, show_endpoints: [{ ep_type: 'signal', name: 'detection', value: true }] },
  ],
  fetchedAt: '2026-01-01T00:00:00.000Z',
};

tap.test('maps Freebox local API data to devices and entities', async () => {
  const snapshot = FreeboxMapper.toSnapshot({ config: { host: 'mafreebox.freebox.fr', appToken: 'token', name: 'Home Freebox' }, rawData: freeboxRawData, online: true, source: 'manual' });
  const devices = FreeboxMapper.toDevices(snapshot);
  const entities = FreeboxMapper.toEntities(snapshot);

  expect(snapshot.router.macAddress).toEqual('f4:ca:e5:5c:ea:14');
  expect(snapshot.capabilities.localControl).toBeTrue();
  expect(devices.some((deviceArg) => deviceArg.id === 'freebox.disk.disk123')).toBeTrue();
  expect(devices.some((deviceArg) => deviceArg.id === 'freebox.host.aa_bb_cc_dd_ee_ff')).toBeTrue();
  expect(entities.find((entityArg) => entityArg.id === 'sensor.home_freebox_rate_down')?.state).toEqual(1234);
  expect(entities.find((entityArg) => entityArg.id === 'sensor.home_freebox_missed_calls')?.state).toEqual(1);
  expect(entities.find((entityArg) => entityArg.id === 'sensor.hitachi_partition_1_3_free_space')?.state).toEqual(25);
  expect(entities.find((entityArg) => entityArg.id === 'switch.home_freebox_wifi')?.state).toEqual('on');
  expect(entities.find((entityArg) => entityArg.id === 'binary_sensor.home_freebox_raid_7_degraded')?.state).toEqual(true);
  expect(entities.find((entityArg) => String(entityArg.platform) === 'device_tracker')?.state).toEqual('home');
  expect(entities.find((entityArg) => String(entityArg.platform) === 'alarm_control_panel')?.state).toEqual('disarmed');
  expect(entities.find((entityArg) => String(entityArg.platform) === 'camera')?.attributes?.streamUrl).toEqual('rtsp://camera/stream');
});

tap.test('maps Freebox service requests to local API commands', async () => {
  const snapshot = FreeboxMapper.toSnapshot({ config: { host: 'mafreebox.freebox.fr', appToken: 'token' }, rawData: freeboxRawData, online: true, source: 'manual' });
  const wifiCommand = FreeboxMapper.commandForService(snapshot, {
    domain: 'freebox',
    service: 'set_wifi_enabled',
    target: {},
    data: { enabled: false },
  });
  const rebootCommand = FreeboxMapper.commandForService(snapshot, {
    domain: 'freebox',
    service: 'reboot',
    target: {},
  });

  expect(wifiCommand?.endpoint).toEqual('wifi/config/');
  expect(wifiCommand?.body).toEqual({ enabled: false });
  expect(rebootCommand?.endpoint).toEqual('system/reboot/');
  expect(rebootCommand?.method).toEqual('POST');
});

export default tap.start();
