import { expect, tap } from '@git.zone/tstest/tapbundle';
import { BrotherClient, BrotherMapper, brotherOids, type IBrotherRawData, type IBrotherSnapshot } from '../../ts/integrations/brother/index.js';

const rawData: IBrotherRawData = {
  [brotherOids.model]: 'MFG:Brother;MDL:HL-L2350DW;CMD:PCL;',
  [brotherOids.serial]: 'BR123',
  [brotherOids.mac]: 'aa:bb:cc:dd:ee:ff',
  [brotherOids.firmware]: '1.2.3',
  [brotherOids.status]: 'Ready',
  [brotherOids.counters]: ['0001040000007b', '01010400000064', '02010400000017'],
  [brotherOids.maintenance]: ['6f010400001d4c', '4101040000251c'],
  [brotherOids.nextcare]: ['82010400002ee0'],
};

tap.test('maps Brother raw SNMP-modeled data to printer snapshot, devices, and entities', async () => {
  const snapshot = BrotherMapper.toSnapshot({
    config: { host: 'printer.local', port: 161, printerType: 'laser' },
    rawData,
    online: true,
    source: 'manual',
  });

  expect(snapshot.printer.manufacturer).toEqual('Brother');
  expect(snapshot.printer.model).toEqual('HL-L2350DW');
  expect(snapshot.printer.serialNumber).toEqual('BR123');
  expect(snapshot.printer.firmware).toEqual('1.2.3');
  expect(snapshot.sensors.status).toEqual('ready');
  expect(snapshot.sensors.page_counter).toEqual(123);
  expect(snapshot.sensors.bw_counter).toEqual(100);
  expect(snapshot.sensors.color_counter).toEqual(23);
  expect(snapshot.sensors.black_toner_remaining).toEqual(75);
  expect(snapshot.sensors.drum_remaining_life).toEqual(95);
  expect(snapshot.sensors.drum_remaining_pages).toEqual(12000);

  const devices = BrotherMapper.toDevices(snapshot);
  const entities = BrotherMapper.toEntities(snapshot);
  expect(devices[0].id).toEqual('brother.printer.br123');
  expect(devices[0].metadata?.source).toEqual('manual');
  expect(devices[0].features.some((featureArg) => featureArg.id === 'black_toner_remaining')).toBeTrue();
  expect(devices[0].state.some((stateArg) => stateArg.featureId === 'page_counter' && stateArg.value === 123)).toBeTrue();

  const tonerEntity = entities.find((entityArg) => entityArg.attributes?.key === 'black_toner_remaining');
  expect(tonerEntity?.id).toEqual('sensor.hl_l2350dw_br123_black_toner_remaining');
  expect(tonerEntity?.state).toEqual(75);
  expect(tonerEntity?.attributes?.unitOfMeasurement).toEqual('%');
  expect(tonerEntity?.available).toBeTrue();
});

tap.test('keeps host-only Brother configs offline instead of faking SNMP success', async () => {
  const client = new BrotherClient({ host: 'printer.local', name: 'Host Only Brother' });
  const snapshot = await client.getSnapshot();

  expect(snapshot.online).toBeFalse();
  expect(snapshot.source).toEqual('runtime');
  expect(snapshot.error).toContain('Native Brother SNMP transport is not implemented');
  expect(await client.ping()).toBeFalse();
});

tap.test('maps offline Brother snapshots with an unavailable status entity', async () => {
  const snapshot: IBrotherSnapshot = {
    printer: { id: 'offline-brother', name: 'Offline Brother', manufacturer: 'Brother' },
    sensors: {},
    online: false,
    updatedAt: '2026-01-01T00:00:00.000Z',
    source: 'runtime',
    error: 'offline',
  };
  const entities = BrotherMapper.toEntities(snapshot);

  expect(entities.length).toEqual(1);
  expect(entities[0].id).toEqual('sensor.offline_brother_status');
  expect(entities[0].state).toEqual('unknown');
  expect(entities[0].available).toBeFalse();
  expect(entities[0].attributes?.error).toEqual('offline');
});

export default tap.start();
