import { expect, tap } from '@git.zone/tstest/tapbundle';
import { AdguardClient, AdguardIntegration, type IAdguardSnapshot } from '../../ts/integrations/adguard/index.js';

const snapshot: IAdguardSnapshot = {
  online: true,
  host: '127.0.0.1',
  port: 3000,
  status: { running: true, version: 'v0.107.45', protection_enabled: false },
  filtering: { enabled: true, filters: [{ name: 'Test', url: 'https://example.test/filter.txt', enabled: true, rules_count: 1 }] },
  queryLog: { enabled: true, interval: 604800000, anonymize_client_ip: false, ignored: [], ignored_enabled: false },
  safebrowsing: { enabled: false },
  safesearch: { enabled: false },
  parental: { enabled: false },
  stats: { num_dns_queries: 1, num_blocked_filtering: 0, avg_processing_time: 0.01 },
};

tap.test('reads AdGuard Home snapshot from local HTTP API endpoints', async () => {
  const originalFetch = globalThis.fetch;
  const calls: Array<{ url: string; method?: string; authorization?: string }> = [];
  globalThis.fetch = (async (urlArg: URL | RequestInfo, initArg?: RequestInit) => {
    calls.push({ url: String(urlArg), method: initArg?.method, authorization: (initArg?.headers as Record<string, string> | undefined)?.authorization });
    const path = new URL(String(urlArg)).pathname;
    const responses: Record<string, unknown> = {
      '/control/status': { running: true, version: 'v0.107.45', protection_enabled: true, http_port: 3000 },
      '/control/filtering/status': { enabled: true, filters: [{ name: 'Filter', url: 'https://example.test/filter.txt', rules_count: 10, enabled: true }] },
      '/control/querylog/config': { enabled: true, interval: 604800000, anonymize_client_ip: false, ignored: [], ignored_enabled: false },
      '/control/safebrowsing/status': { enabled: true },
      '/control/safesearch/status': { enabled: false },
      '/control/parental/status': { enabled: false },
      '/control/stats': { num_dns_queries: 40, num_blocked_filtering: 10, avg_processing_time: 0.02 },
      '/control/version.json': { disabled: true },
    };
    return new Response(JSON.stringify(responses[path] || {}), { status: 200, headers: { 'content-type': 'application/json' } });
  }) as typeof globalThis.fetch;

  try {
    const result = await new AdguardClient({ host: '127.0.0.1', port: 3000, ssl: false, username: 'admin', password: 'secret' }).getSnapshot();
    expect(result.online).toBeTrue();
    expect(result.status.version).toEqual('v0.107.45');
    expect(result.stats.num_blocked_filtering).toEqual(10);
    expect(calls.some((callArg) => callArg.url === 'http://127.0.0.1:3000/control/status')).toBeTrue();
    expect(calls[0].authorization).toEqual(`Basic ${Buffer.from('admin:secret').toString('base64')}`);
  } finally {
    globalThis.fetch = originalFetch;
  }
});

tap.test('executes live AdGuard commands only through HTTP client or executor', async () => {
  const originalFetch = globalThis.fetch;
  const calls: Array<{ url: string; method?: string; body?: string }> = [];
  globalThis.fetch = (async (urlArg: URL | RequestInfo, initArg?: RequestInit) => {
    calls.push({ url: String(urlArg), method: initArg?.method, body: initArg?.body as string | undefined });
    return new Response('{}', { status: 200, headers: { 'content-type': 'application/json' } });
  }) as typeof globalThis.fetch;

  try {
    const runtime = await new AdguardIntegration().setup({ host: '127.0.0.1', port: 3000, snapshot }, {});
    const result = await runtime.callService?.({
      domain: 'switch',
      service: 'turn_on',
      target: { entityId: 'switch.adguard_home_protection' },
    });
    expect(result?.success).toBeTrue();
    expect(calls[0].url).toEqual('http://127.0.0.1:3000/control/protection');
    expect(calls[0].method).toEqual('POST');
    expect(JSON.parse(calls[0].body || '{}')).toEqual({ enabled: true });
    await runtime.destroy();
  } finally {
    globalThis.fetch = originalFetch;
  }
});

tap.test('does not report snapshot-only AdGuard commands as successful', async () => {
  const runtime = await new AdguardIntegration().setup({ snapshot: { ...snapshot, host: undefined } }, {});
  const protectionEntity = (await runtime.entities()).find((entityArg) => entityArg.attributes?.adguardSwitchKey === 'protection');
  const result = await runtime.callService?.({
    domain: 'switch',
    service: 'turn_on',
    target: { entityId: protectionEntity?.id },
  });
  expect(result?.success).toBeFalse();
  expect(result?.error).toEqual('AdGuard Home live commands require config.host or commandExecutor; snapshot-only commands are not reported as successful.');
  await runtime.destroy();
});

export default tap.start();
