import { wakeOnLanDefaultBroadcastAddress, wakeOnLanDefaultBroadcastPort } from './wake_on_lan.constants.js';
import type { IWakeOnLanMagicPacket } from './wake_on_lan.types.js';

export const normalizeWakeOnLanMac = (valueArg?: string): string | undefined => {
  if (!valueArg) {
    return undefined;
  }
  const compact = valueArg.replace(/[^0-9a-f]/gi, '').toLowerCase();
  return compact.length === 12 ? compact.match(/.{1,2}/g)?.join(':') : undefined;
};

export const compactWakeOnLanMac = (valueArg: string): string => {
  const normalized = normalizeWakeOnLanMac(valueArg);
  if (!normalized) {
    throw new Error('Wake on LAN requires a valid MAC address.');
  }
  return normalized.replaceAll(':', '');
};

export const createWakeOnLanMagicPacketBuffer = (macAddressArg: string): Buffer => {
  const compactMac = compactWakeOnLanMac(macAddressArg);
  return Buffer.from(`${'ff'.repeat(6)}${compactMac.repeat(16)}`, 'hex');
};

export const createWakeOnLanMagicPacket = (macAddressArg: string, optionsArg: { broadcastAddress?: string; broadcastPort?: number } = {}): IWakeOnLanMagicPacket => {
  const normalizedMac = normalizeWakeOnLanMac(macAddressArg);
  if (!normalizedMac) {
    throw new Error('Wake on LAN requires a valid MAC address.');
  }
  const packet = createWakeOnLanMagicPacketBuffer(normalizedMac);
  return {
    macAddress: normalizedMac,
    compactMac: normalizedMac.replaceAll(':', ''),
    broadcastAddress: optionsArg.broadcastAddress || wakeOnLanDefaultBroadcastAddress,
    broadcastPort: optionsArg.broadcastPort ?? wakeOnLanDefaultBroadcastPort,
    byteLength: packet.byteLength,
    bytes: [...packet],
    hex: packet.toString('hex'),
    base64: packet.toString('base64'),
  };
};
