import { expect, tap } from '@git.zone/tstest/tapbundle';
import { DdwrtConfigFlow, DdwrtMapper, createDdwrtDiscoveryDescriptor, type IDdwrtSnapshot } from '../../ts/integrations/ddwrt/index.js';

const wirelessResponse = "{active_wireless::'AA:BB:CC:DD:EE:FF','ath0'}";
const lanResponse = "{arp_table::'192.168.1.10','AA:BB:CC:DD:EE:FF','br0'}{dhcp_leases::'phone','192.168.1.10','AA:BB:CC:DD:EE:FF','hostid','3600'}";
const snapshot: IDdwrtSnapshot = DdwrtMapper.toSnapshot({
  host: '192.168.1.1',
  name: 'Lab Router',
  rawStatus: {
    wireless: DdwrtMapper.parseDdwrtResponse(wirelessResponse),
    lan: DdwrtMapper.parseDdwrtResponse(lanResponse),
  },
});

tap.test('matches DD-WRT HTTP status and manual snapshot candidates', async () => {
  const descriptor = createDdwrtDiscoveryDescriptor();
  const httpMatcher = descriptor.getMatchers().find((matcherArg) => matcherArg.id === 'ddwrt-http-status-match');
  const manualMatcher = descriptor.getMatchers().find((matcherArg) => matcherArg.id === 'ddwrt-manual-match');
  const dhcpMatcher = descriptor.getMatchers().find((matcherArg) => matcherArg.id === 'ddwrt-dhcp-match');

  const http = await httpMatcher?.matches({ host: '192.168.1.1', body: wirelessResponse, lanResponse }, {});
  const manual = await manualMatcher?.matches({ snapshot }, {});
  const dhcp = await dhcpMatcher?.matches({ host: '192.168.1.1', hostname: 'dd-wrt-router', macAddress: 'AA-BB-CC-DD-EE-FF' }, {});

  expect(http?.matched).toBeTrue();
  expect(http?.confidence).toEqual('certain');
  expect(http?.candidate?.integrationDomain).toEqual('ddwrt');
  expect(http?.candidate?.metadata?.discoveryProtocol).toEqual('http-status');
  expect(manual?.matched).toBeTrue();
  expect(manual?.confidence).toEqual('certain');
  expect(manual?.candidate?.metadata?.snapshot).toEqual(snapshot);
  expect(dhcp?.matched).toBeTrue();
  expect(dhcp?.candidate?.macAddress).toEqual('aa:bb:cc:dd:ee:ff');
});

tap.test('builds config flow output and validates DD-WRT inputs', async () => {
  const flow = new DdwrtConfigFlow();
  const step = await flow.start({
    source: 'manual',
    integrationDomain: 'ddwrt',
    id: 'router-1',
    host: '192.168.1.1',
    name: 'Lab Router',
  }, {});

  const done = await step.submit?.({ username: 'admin', password: 'secret', ssl: false, verifySsl: true, wirelessOnly: true, timeoutMs: '2500' });
  expect(done?.kind).toEqual('done');
  expect(done?.config?.host).toEqual('192.168.1.1');
  expect(done?.config?.username).toEqual('admin');
  expect(done?.config?.password).toEqual('secret');
  expect(done?.config?.wirelessOnly).toBeTrue();
  expect(done?.config?.timeoutMs).toEqual(2500);

  const missingCredentials = await step.submit?.({});
  expect(missingCredentials?.kind).toEqual('error');
  expect(missingCredentials?.error || '').toContain('username and password');

  const statusDone = await step.submit?.({ wirelessStatus: wirelessResponse, lanStatus: lanResponse });
  expect(statusDone?.kind).toEqual('done');
  expect(statusDone?.config?.rawStatus?.wireless?.active_wireless).toContain('AA:BB:CC:DD:EE:FF');

  const snapshotDone = await step.submit?.({ snapshotJson: JSON.stringify(snapshot) });
  expect(snapshotDone?.kind).toEqual('done');
  expect(snapshotDone?.config?.snapshot?.router.name).toEqual('Lab Router');

  const invalidSnapshot = await step.submit?.({ username: 'admin', password: 'secret', snapshotJson: '{"connected":true}' });
  expect(invalidSnapshot?.kind).toEqual('error');
});

export default tap.start();
