import { expect, tap } from '@git.zone/tstest/tapbundle';
import { HddtempConfigFlow, HddtempMapper, createHddtempDiscoveryDescriptor } from '../../ts/integrations/hddtemp/index.js';

const rawData = '|/dev/sda|Samsung SSD 860|39|C||/dev/sdb|WDC WD20EFRX|41|C|';

tap.test('matches manual hddtemp host entries and creates config flow output', async () => {
  const descriptor = createHddtempDiscoveryDescriptor();
  const matcher = descriptor.getMatchers().find((matcherArg) => matcherArg.id === 'hddtemp-manual-match');
  const result = await matcher!.matches({ host: 'nas.local', name: 'NAS hddtemp', disks: ['/dev/sda'] }, {});

  expect(result.matched).toBeTrue();
  expect(result.candidate?.integrationDomain).toEqual('hddtemp');
  expect(result.candidate?.port).toEqual(7634);

  const validation = await descriptor.getValidators()[0].validate(result.candidate!, {});
  expect(validation.matched).toBeTrue();

  const done = await (await new HddtempConfigFlow().start(result.candidate!, {})).submit!({});
  expect(done.kind).toEqual('done');
  expect(done.config?.host).toEqual('nas.local');
  expect(done.config?.port).toEqual(7634);
  expect(done.config?.disks?.[0]).toEqual('/dev/sda');
});

tap.test('matches custom TCP candidates with raw hddtemp daemon output', async () => {
  const descriptor = createHddtempDiscoveryDescriptor();
  const matcher = descriptor.getMatchers().find((matcherArg) => matcherArg.id === 'hddtemp-tcp-match');
  const result = await matcher!.matches({ host: '192.0.2.10', port: 7634, banner: rawData }, {});

  expect(result.matched).toBeTrue();
  expect(result.confidence).toEqual('certain');
  expect(result.candidate?.host).toEqual('192.0.2.10');
  expect((result.candidate?.metadata?.disks as string[])[0]).toEqual('/dev/sda');
  expect(result.candidate?.metadata?.rawData).toEqual(rawData);
});

tap.test('matches snapshot-only hddtemp setup without requiring live transport', async () => {
  const snapshot = HddtempMapper.toSnapshot({ config: { name: 'Snapshot HDD' }, rawData, online: true, source: 'manual' });
  const descriptor = createHddtempDiscoveryDescriptor();
  const matcher = descriptor.getMatchers().find((matcherArg) => matcherArg.id === 'hddtemp-manual-match');
  const result = await matcher!.matches({ snapshot }, {});

  expect(result.matched).toBeTrue();
  expect(result.candidate?.metadata?.snapshot).toEqual(snapshot);

  const done = await (await new HddtempConfigFlow().start(result.candidate!, {})).submit!({});
  expect(done.kind).toEqual('done');
  expect(done.config?.snapshot?.disks[0].device).toEqual('/dev/sda');
  expect(done.config?.transport).toEqual('snapshot');
});

tap.test('rejects generic candidates and hddtemp candidates without usable data', async () => {
  const descriptor = createHddtempDiscoveryDescriptor();
  const matcher = descriptor.getMatchers().find((matcherArg) => matcherArg.id === 'hddtemp-manual-match');
  const result = await matcher!.matches({ name: 'Generic temperature sensor' }, {});
  expect(result.matched).toBeFalse();

  const validation = await descriptor.getValidators()[0].validate({ source: 'manual', name: 'hddtemp without endpoint' }, {});
  expect(validation.matched).toBeFalse();
  expect(validation.reason).toContain('lacks a host');
});

export default tap.start();
