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

const snapshot: IAdguardSnapshot = {
  online: true,
  host: '192.168.1.2',
  port: 3000,
  name: 'Home DNS',
  status: {
    running: true,
    version: 'v0.107.45',
    protection_enabled: true,
    language: 'en',
    dns_port: 53,
  },
  filtering: {
    enabled: true,
    filters: [
      { id: 1, name: 'AdGuard DNS filter', url: 'https://example.test/filter.txt', enabled: false, rules_count: 1200 },
    ],
  },
  queryLog: {
    enabled: false,
    interval: 604800000,
    anonymize_client_ip: false,
    ignored: [],
    ignored_enabled: false,
  },
  safebrowsing: { enabled: true },
  safesearch: { enabled: false, google: true, youtube: true },
  parental: { enabled: true, sensitivity: 13 },
  stats: {
    num_dns_queries: 200,
    num_blocked_filtering: 50,
    num_replaced_parental: 3,
    num_replaced_safebrowsing: 4,
    num_replaced_safesearch: 5,
    avg_processing_time: 0.012345,
  },
  update: {
    disabled: false,
    new_version: 'v0.107.46',
    announcement: 'AdGuard Home v0.107.46 is available.',
    announcement_url: 'https://github.com/AdguardTeam/AdGuardHome/releases/tag/v0.107.46',
  },
};

tap.test('maps AdGuard Home status, controls, update, and statistics sensors', async () => {
  const devices = AdguardMapper.toDevices(snapshot);
  const entities = AdguardMapper.toEntities(snapshot);

  expect(devices[0].id).toEqual('adguard.service.192_168_1_2_3000');
  expect(devices[0].online).toBeTrue();
  expect(entities.find((entityArg) => entityArg.id === 'switch.home_dns_protection')?.state).toEqual('on');
  expect(entities.find((entityArg) => entityArg.id === 'switch.home_dns_query_log')?.state).toEqual('off');
  expect(entities.find((entityArg) => entityArg.id === 'switch.home_dns_safe_browsing')?.state).toEqual('on');
  expect(entities.find((entityArg) => entityArg.id === 'sensor.home_dns_dns_queries')?.state).toEqual(200);
  expect(entities.find((entityArg) => entityArg.id === 'sensor.home_dns_dns_queries_blocked_ratio')?.state).toEqual(25);
  expect(entities.find((entityArg) => entityArg.id === 'sensor.home_dns_average_processing_speed')?.state).toEqual(12.35);
  expect(entities.find((entityArg) => entityArg.id === 'sensor.home_dns_rules_count')?.state).toEqual(1200);
  expect(entities.find((entityArg) => entityArg.id === 'update.home_dns')?.attributes?.latestVersion).toEqual('v0.107.46');
});

tap.test('models safe AdGuard service commands with validated payloads', async () => {
  const turnOffCommand = AdguardMapper.commandForService(snapshot, {
    domain: 'switch',
    service: 'turn_off',
    target: { entityId: 'switch.home_dns_protection' },
  });
  const enableUrlCommand = AdguardMapper.commandForService(snapshot, {
    domain: 'adguard',
    service: 'enable_url',
    target: {},
    data: { url: 'https://example.test/filter.txt' },
  });
  const unsafeAddCommand = AdguardMapper.commandForService(snapshot, {
    domain: 'adguard',
    service: 'add_url',
    target: {},
    data: { name: 'Bad', url: 'relative.txt' },
  });

  expect(Boolean(turnOffCommand && !('error' in turnOffCommand))).toBeTrue();
  if (turnOffCommand && !('error' in turnOffCommand)) {
    expect(turnOffCommand.path).toEqual('/protection');
    expect(turnOffCommand.payload).toEqual({ enabled: false });
  }
  expect(Boolean(enableUrlCommand && !('error' in enableUrlCommand))).toBeTrue();
  if (enableUrlCommand && !('error' in enableUrlCommand)) {
    expect(enableUrlCommand.path).toEqual('/filtering/set_url');
    expect(enableUrlCommand.payload).toEqual({
      url: 'https://example.test/filter.txt',
      whitelist: false,
      data: { name: 'AdGuard DNS filter', url: 'https://example.test/filter.txt', enabled: true },
    });
  }
  expect('error' in unsafeAddCommand!).toBeTrue();
});

export default tap.start();
