import { createServer } from 'node:http';
import { expect, tap } from '@git.zone/tstest/tapbundle';
import { GlancesClient, type IGlancesRawData } from '../../ts/integrations/glances/index.js';

const rawData: IGlancesRawData = {
  system: { hostname: 'nas', os_name: 'Linux', platform: 'Linux' },
  quicklook: { cpu: 12.5 },
  mem: { percent: 55.5, used: 2147483648, free: 1073741824 },
  fs: [{ mnt_point: '/', used: 107374182400, size: 214748364800, percent: 50 }],
  network: [{ interface_name: 'eth0', rx: 600, tx: 300, time_since_update: 3, is_up: true, speed: 1073741824 }],
  load: { min1: 0.12, min5: 0.24, min15: 0.42 },
  processcount: { running: 3, total: 144, thread: 300, sleeping: 141 },
  sensors: [{ label: 'CPU Core', type: 'temperature_core', value: 48.2 }],
};

tap.test('probes Glances v4 then v3 over local HTTP', async () => {
  const requests: string[] = [];
  const server = createServer((requestArg, responseArg) => {
    requests.push(requestArg.url || '');
    if (requestArg.url === '/api/4/all') {
      responseArg.statusCode = 404;
      responseArg.end('no v4 here');
      return;
    }
    if (requestArg.url === '/api/3/all') {
      expect(requestArg.headers.authorization).toEqual(`Basic ${Buffer.from('glances:secret').toString('base64')}`);
      responseArg.setHeader('content-type', 'application/json');
      responseArg.end(JSON.stringify(rawData));
      return;
    }
    responseArg.statusCode = 404;
    responseArg.end('not found');
  });

  await new Promise<void>((resolve) => server.listen(0, '127.0.0.1', resolve));
  try {
    const address = server.address();
    const port = typeof address === 'object' && address ? address.port : 0;
    const snapshot = await new GlancesClient({ host: '127.0.0.1', port, username: 'glances', password: 'secret', timeoutMs: 1000 }).getSnapshot();

    expect(requests).toEqual(['/api/4/all', '/api/3/all']);
    expect(snapshot.online).toBeTrue();
    expect(snapshot.apiVersion).toEqual(3);
    expect(snapshot.host.hostname).toEqual('nas');
    expect(snapshot.sensorData.network?.eth0?.rx).toEqual(200);
    expect(snapshot.sensors.find((sensorArg) => sensorArg.key === 'cpu_use_percent')?.value).toEqual(12.5);
  } finally {
    await new Promise<void>((resolve, reject) => server.close((errorArg) => errorArg ? reject(errorArg) : resolve()));
  }
});

tap.test('does not fake refresh success without HTTP endpoint or snapshot', async () => {
  const client = new GlancesClient({});
  const snapshot = await client.getSnapshot();
  const result = await client.refresh();

  expect(snapshot.online).toBeFalse();
  expect(snapshot.sensors.length).toEqual(0);
  expect(result.success).toBeFalse();
  expect(result.error).toContain('endpoint');
});

export default tap.start();
