import { expect, tap } from '@git.zone/tstest/tapbundle';
import { FritzboxCallmonitorConfigFlow, createFritzboxCallmonitorDiscoveryDescriptor } from '../../ts/integrations/fritzbox_callmonitor/index.js';

tap.test('matches manual FRITZ!Box Call Monitor snapshots and event lines', async () => {
  const descriptor = createFritzboxCallmonitorDiscoveryDescriptor();
  const matcher = descriptor.getMatchers()[0];
  const result = await matcher.matches({
    snapshot: {
      connected: true,
      monitor: { host: '192.168.178.1', port: 1012, name: 'Phone', serialNumber: 'AABBCCDDEEFF' },
      call: { state: 'idle', attributes: {} },
      contacts: [],
      events: [],
    },
  }, {});
  const eventResult = await matcher.matches({
    eventLines: ['01.01.26 12:00:00;RING;0;030123456;+4930999;SIP0;'],
  }, {});
  const validator = descriptor.getValidators()[0];
  const validation = await validator.validate(result.candidate!, {});

  expect(result.matched).toBeTrue();
  expect(result.candidate?.integrationDomain).toEqual('fritzbox_callmonitor');
  expect(result.candidate?.port).toEqual(1012);
  expect(eventResult.confidence).toEqual('certain');
  expect(validation.matched).toBeTrue();
  expect(validation.metadata?.phonebookApiImplemented).toBeFalse();
});

tap.test('matches FRITZ SSDP advertisements without claiming upstream SSDP support', async () => {
  const descriptor = createFritzboxCallmonitorDiscoveryDescriptor();
  const matcher = descriptor.getMatchers()[1];
  const result = await matcher.matches({
    st: 'urn:schemas-upnp-org:device:fritzbox:1',
    ssdpLocation: 'http://192.168.178.1:49000/rootDesc.xml',
    upnp: {
      friendlyName: 'FRITZ!Box 7590',
      modelName: 'FRITZ!Box 7590',
      UDN: 'uuid:abcdef01-2345-6789-abcd-ef0123456789',
    },
  }, {});

  expect(result.matched).toBeTrue();
  expect(result.confidence).toEqual('certain');
  expect(result.candidate?.host).toEqual('192.168.178.1');
  expect(result.candidate?.port).toEqual(1012);
  expect(result.candidate?.metadata?.upstreamSupportsSsdp).toBeFalse();
});

tap.test('builds config flow for host, manual contacts, prefixes, and event lines', async () => {
  const flow = new FritzboxCallmonitorConfigFlow();
  const step = await flow.start({ source: 'manual', host: '192.168.178.1', name: 'Phone' }, {});
  const done = await step.submit!({
    host: '192.168.178.1',
    port: 1012,
    username: 'homeassistant',
    password: 'secret',
    phonebookName: 'Phone',
    prefixes: '+49,+4930',
    contactsJson: JSON.stringify([{ name: 'Alice', numbers: ['+4930123456'], vip: true }]),
    eventLines: '01.01.26 12:00:00;RING;0;030123456;+4930999;SIP0;',
  });
  const malformed = await step.submit!({ host: '192.168.178.1', prefixes: '   ' });

  expect(done.kind).toEqual('done');
  expect(done.config?.port).toEqual(1012);
  expect(done.config?.contacts?.[0].name).toEqual('Alice');
  expect(done.config?.eventLines?.length).toEqual(1);
  expect(done.config?.metadata?.phonebookApiImplemented).toBeFalse();
  expect(malformed.kind).toEqual('error');
});

export default tap.start();
