import { expect, tap } from '@git.zone/tstest/tapbundle';
import { DelugeConfigFlow, DelugeMapper, createDelugeDiscoveryDescriptor, type IDelugeRawData } from '../../ts/integrations/deluge/index.js';

const rawData: Partial<IDelugeRawData> = {
  webUi: {
    connected: true,
    stats: { download_rate: 0, upload_rate: 0 },
    torrents: {},
  },
};

tap.test('matches manual Deluge Web endpoints', async () => {
  const descriptor = createDelugeDiscoveryDescriptor();
  const matcher = descriptor.getMatchers().find((matcherArg) => matcherArg.id === 'deluge-manual-match');
  const match = await matcher!.matches({ host: '192.168.1.5', password: 'deluge', metadata: { deluge: true } }, {});

  expect(match.matched).toBeTrue();
  expect(match.candidate?.integrationDomain).toEqual('deluge');
  expect(match.candidate?.host).toEqual('192.168.1.5');
  expect(match.candidate?.port).toEqual(8112);
  expect(match.candidate?.metadata?.url).toEqual('http://192.168.1.5:8112');
});

tap.test('matches HTTP Deluge Web JSON-RPC candidates', async () => {
  const matcher = createDelugeDiscoveryDescriptor().getMatchers().find((matcherArg) => matcherArg.id === 'deluge-http-match');
  const match = await matcher!.matches({ url: 'http://deluge.local:8112/json', path: '/json', name: 'Deluge Web' }, {});

  expect(match.matched).toBeTrue();
  expect(match.confidence).toEqual('high');
  expect(match.candidate?.metadata?.webPort).toEqual(8112);
});

tap.test('creates config from Deluge snapshots without requiring live credentials', async () => {
  const snapshot = DelugeMapper.toSnapshot({ config: { name: 'Snapshot Deluge' }, rawData, online: true, source: 'manual' });
  const matcher = createDelugeDiscoveryDescriptor().getMatchers().find((matcherArg) => matcherArg.id === 'deluge-manual-match');
  const match = await matcher!.matches({ metadata: { snapshot } }, {});
  const done = await (await new DelugeConfigFlow().start(match.candidate!, {})).submit!({});

  expect(match.matched).toBeTrue();
  expect(done.kind).toEqual('done');
  expect(done.config?.snapshot?.device.name).toEqual('Snapshot Deluge');
});

tap.test('rejects Deluge candidates without a local source', async () => {
  const validation = await createDelugeDiscoveryDescriptor().getValidators()[0].validate({
    source: 'manual',
    integrationDomain: 'deluge',
    name: 'No host',
  }, {});

  expect(validation.matched).toBeFalse();
  expect(validation.reason).toEqual('Deluge candidate lacks a host, snapshot, raw data, or injected client.');
});

export default tap.start();
