import { expect, tap } from '@git.zone/tstest/tapbundle';
import { WakeOnLanClient, WakeOnLanMapper, type IWakeOnLanSnapshot } from '../../ts/integrations/wake_on_lan/index.js';

const snapshot: IWakeOnLanSnapshot = WakeOnLanMapper.toSnapshot({
  macAddress: 'AA-BB-CC-DD-EE-FF',
  host: '192.168.1.20',
  name: 'Gaming PC',
  broadcastAddress: '192.168.1.255',
  broadcastPort: 7,
  entityTypes: ['button', 'switch'],
  connected: true,
  state: false,
});

tap.test('constructs Home Assistant-compatible magic packets', async () => {
  const packet = WakeOnLanClient.createMagicPacket('AA-BB-CC-DD-EE-FF', { broadcastAddress: '192.168.1.255', broadcastPort: 7 });

  expect(packet.byteLength).toEqual(102);
  expect(packet.hex.slice(0, 12)).toEqual('ffffffffffff');
  expect(packet.hex.slice(12, 24)).toEqual('aabbccddeeff');
  expect(packet.hex.endsWith('aabbccddeeff')).toBeTrue();
  expect(packet.broadcastAddress).toEqual('192.168.1.255');
  expect(packet.broadcastPort).toEqual(7);
});

tap.test('maps Wake on LAN targets to button and switch entities', async () => {
  const entities = WakeOnLanMapper.toEntities(snapshot);
  const button = entities.find((entityArg) => entityArg.platform === 'button');
  const wolSwitch = entities.find((entityArg) => entityArg.platform === 'switch');

  expect(button?.id).toEqual('button.gaming_pc_wake');
  expect(button?.attributes?.nativeAction).toEqual('send_magic_packet');
  expect(button?.attributes?.macAddress).toEqual('aa:bb:cc:dd:ee:ff');
  expect(wolSwitch?.id).toEqual('switch.gaming_pc_power');
  expect(wolSwitch?.state).toEqual('off');
  expect(wolSwitch?.attributes?.assumedState).toBeFalse();

  const devices = WakeOnLanMapper.toDevices(snapshot);
  expect(devices[0].features.some((featureArg) => featureArg.id === 'magic_packet')).toBeTrue();
  expect(devices[0].features.some((featureArg) => featureArg.id === 'power')).toBeTrue();
});

tap.test('maps service and entity controls to explicit magic packet commands', async () => {
  const directCommand = WakeOnLanMapper.commandForService(snapshot, {
    domain: 'wake_on_lan',
    service: 'send_magic_packet',
    target: {},
    data: { mac: 'AA:BB:CC:DD:EE:FF', broadcast_address: '10.0.0.255', broadcast_port: 9 },
  });

  expect(directCommand?.method).toEqual('wakeonlan.send_magic_packet');
  expect(directCommand?.packet?.byteLength).toEqual(102);
  expect(directCommand?.broadcastAddress).toEqual('10.0.0.255');
  expect(directCommand?.broadcastPort).toEqual(9);

  const buttonCommand = WakeOnLanMapper.commandForService(snapshot, {
    domain: 'button',
    service: 'press',
    target: { entityId: 'button.gaming_pc_wake' },
    data: {},
  });

  expect(buttonCommand?.type).toEqual('button_press');
  expect(buttonCommand?.normalizedMac).toEqual('aa:bb:cc:dd:ee:ff');
  expect(buttonCommand?.packet?.hex.slice(0, 12)).toEqual('ffffffffffff');
});

export default tap.start();
