import { expect, tap } from '@git.zone/tstest/tapbundle';
import { DoorbirdConfigFlow, DoorbirdMapper, createDoorbirdDiscoveryDescriptor, type IDoorbirdInfo } from '../../ts/integrations/doorbird/index.js';

tap.test('matches DoorBird zeroconf records and creates config flow output', async () => {
  const descriptor = createDoorbirdDiscoveryDescriptor();
  const mdnsMatcher = descriptor.getMatchers().find((matcherArg) => matcherArg.id === 'doorbird-mdns-match');
  const result = await mdnsMatcher!.matches({
    type: '_axis-video._tcp.local.',
    name: 'Front Door._axis-video._tcp.local.',
    addresses: ['192.168.1.20'],
    properties: { macaddress: '1CCAE3AABBCC' },
  }, {});

  expect(result.matched).toBeTrue();
  expect(result.normalizedDeviceId).toEqual('1ccae3aabbcc');
  expect(result.candidate?.integrationDomain).toEqual('doorbird');
  expect(result.candidate?.host).toEqual('192.168.1.20');
  expect(result.candidate?.metadata?.mdnsType).toEqual('_axis-video._tcp');

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

  const done = await (await new DoorbirdConfigFlow().start(result.candidate!, {})).submit!({ username: 'user', password: 'secret', name: 'Front Door', events: 'doorbell, motion' });
  expect(done.kind).toEqual('done');
  expect(done.config?.host).toEqual('192.168.1.20');
  expect(done.config?.port).toEqual(80);
  expect(done.config?.username).toEqual('user');
  expect(done.config?.password).toEqual('secret');
  expect(done.config?.macAddress).toEqual('1ccae3aabbcc');
  expect(done.config?.events).toEqual(['doorbell', 'motion']);
});

tap.test('matches manual snapshot entries without live HTTP credentials', async () => {
  const rawInfo: IDoorbirdInfo = {
    FIRMWARE: '000122',
    BUILD_NUMBER: '42',
    'DEVICE-TYPE': 'D1101V',
    PRIMARY_MAC_ADDR: '1CCAE3AABBCC',
    RELAYS: ['1'],
  };
  const snapshot = DoorbirdMapper.toSnapshot({ config: { name: 'Static DoorBird' }, rawData: { info: rawInfo, status: { doorbell: false, motion: true } }, online: true, source: 'manual' });
  const descriptor = createDoorbirdDiscoveryDescriptor();
  const manualMatcher = descriptor.getMatchers().find((matcherArg) => matcherArg.id === 'doorbird-manual-match');
  const match = await manualMatcher!.matches({ name: 'DoorBird import', snapshot }, {});

  expect(match.matched).toBeTrue();
  expect(match.candidate?.metadata?.snapshot).toEqual(snapshot);
  const validation = await descriptor.getValidators()[0].validate(match.candidate!, {});
  expect(validation.matched).toBeTrue();

  const done = await (await new DoorbirdConfigFlow().start(match.candidate!, {})).submit!({});
  expect(done.kind).toEqual('done');
  expect(done.config?.snapshot?.status.motion).toBeTrue();
  expect(done.config?.password).toBeUndefined();
});

tap.test('rejects non-DoorBird and unusable zeroconf candidates', async () => {
  const descriptor = createDoorbirdDiscoveryDescriptor();
  const mdnsMatcher = descriptor.getMatchers().find((matcherArg) => matcherArg.id === 'doorbird-mdns-match');
  const generic = await mdnsMatcher!.matches({ type: '_axis-video._tcp.local.', addresses: ['192.168.1.21'], properties: { macaddress: '000000AABBCC' } }, {});
  const linkLocal = await mdnsMatcher!.matches({ type: '_axis-video._tcp.local.', addresses: ['169.254.1.2'], properties: { macaddress: '1CCAE3AABBCC' } }, {});
  const manualMatcher = descriptor.getMatchers().find((matcherArg) => matcherArg.id === 'doorbird-manual-match');
  const manual = await manualMatcher!.matches({ name: 'Generic camera' }, {});

  expect(generic.matched).toBeFalse();
  expect(linkLocal.matched).toBeFalse();
  expect(manual.matched).toBeFalse();
});

export default tap.start();
