import * as plugins from '../../plugins.js';
import type { IIntegrationEntity, IIntegrationEvent, IServiceCallRequest } from '../../core/types.js';
import { ddwrtAttribution, ddwrtDefaultHttpPort, ddwrtDefaultHttpsPort, ddwrtDefaultSsl, ddwrtDefaultVerifySsl, ddwrtDefaultWirelessOnly, ddwrtDisplayName, ddwrtDomain, ddwrtManufacturer } from './ddwrt.constants.js';
import type { IDdwrtClientDevice, IDdwrtCommand, IDdwrtConfig, IDdwrtDhcpLease, IDdwrtEvent, IDdwrtRawStatusSet, IDdwrtSensorMap, IDdwrtSnapshot, IDdwrtStatusData, TDdwrtClientSource } from './ddwrt.types.js';

const ddwrtDataRegex = /\{(\w+)::([^}]*)\}/g;
const macRegex = /(([0-9A-Fa-f]{1,2}:){5}[0-9A-Fa-f]{1,2})/;
const ipv4Regex = /^(?:\d{1,3}\.){3}\d{1,3}$/;

export class DdwrtMapper {
  public static parseDdwrtResponse(dataArg: string): IDdwrtStatusData {
    const result: IDdwrtStatusData = {};
    for (const match of dataArg.matchAll(ddwrtDataRegex)) {
      result[match[1]] = match[2];
    }
    return result;
  }

  public static toStatusData(valueArg: unknown): IDdwrtStatusData | undefined {
    if (!valueArg) {
      return undefined;
    }
    if (typeof valueArg === 'string') {
      const parsed = this.parseDdwrtResponse(valueArg);
      if (Object.keys(parsed).length) {
        return parsed;
      }
      try {
        const parsedJson = JSON.parse(valueArg) as unknown;
        return this.toStatusData(parsedJson);
      } catch {
        return undefined;
      }
    }
    if (typeof valueArg === 'object' && !Array.isArray(valueArg)) {
      const result: IDdwrtStatusData = {};
      for (const [key, value] of Object.entries(valueArg as Record<string, unknown>)) {
        if (typeof value === 'string') {
          result[key] = value;
        } else if (value !== undefined && value !== null) {
          result[key] = String(value);
        }
      }
      return Object.keys(result).length ? result : undefined;
    }
    return undefined;
  }

  public static toSnapshot(configArg: IDdwrtConfig = {}, overridesArg: Partial<IDdwrtSnapshot> = {}, eventsArg: IDdwrtEvent[] = []): IDdwrtSnapshot {
    const source = configArg.snapshot;
    const rawStatus = this.rawStatus(configArg, overridesArg, source);
    const wirelessOnly = overridesArg.router?.wirelessOnly ?? this.wirelessOnly(configArg, source?.router.wirelessOnly);
    const ssl = overridesArg.router?.ssl ?? this.ssl(configArg, source?.router.ssl);
    const port = overridesArg.router?.port || configArg.port || source?.router.port || (ssl ? ddwrtDefaultHttpsPort : ddwrtDefaultHttpPort);
    const host = this.host(configArg) || source?.router.host;
    const leases = this.mergeLeases([
      ...(source?.leases || []),
      ...(configArg.leases || []),
      ...(overridesArg.leases || []),
      ...this.parseDhcpLeases(rawStatus.lan?.dhcp_leases),
    ]);
    const leaseMap = new Map(leases.map((leaseArg) => [leaseArg.macAddress, leaseArg]));
    const wirelessClients = this.parseActiveClients(rawStatus.wireless?.active_wireless, 'wireless', leaseMap);
    const lanClients = this.parseActiveClients(rawStatus.lan?.arp_table, 'arp', leaseMap);
    const selectedClients = wirelessOnly ? wirelessClients : lanClients.length ? lanClients : wirelessClients;
    const clients = this.mergeClients([
      ...(source?.clients || []),
      ...(configArg.clients || []),
      ...selectedClients,
      ...(overridesArg.clients || []),
    ], wirelessOnly, leaseMap);
    const hasData = Boolean(rawStatus.wireless || rawStatus.lan || clients.length || leases.length || Object.keys(configArg.sensors || {}).length);
    const connected = overridesArg.connected ?? configArg.connected ?? source?.connected ?? hasData;
    const sourceName = overridesArg.source || source?.source || (hasData ? 'manual' : 'runtime');
    const name = overridesArg.router?.name || configArg.name || source?.router.name || host || ddwrtDisplayName;
    const routerId = overridesArg.router?.id || configArg.id || source?.router.id || this.normalizeMac(configArg.macAddress || configArg.mac) || host || name;
    const updatedAt = overridesArg.updatedAt || source?.updatedAt || new Date().toISOString();
    const sensors = this.sensorMap({
      ...source?.sensors,
      ...configArg.sensors,
      ...overridesArg.sensors,
      connected,
      wireless_only: wirelessOnly,
      tracked_clients: clients.length,
      active_wireless_clients: wirelessClients.length,
      active_lan_clients: lanClients.length,
      dhcp_leases: leases.length,
    });

    return {
      connected,
      source: sourceName,
      router: {
        ...source?.router,
        ...overridesArg.router,
        id: routerId,
        name,
        host,
        port,
        ssl,
        verifySsl: overridesArg.router?.verifySsl ?? this.verifySsl(configArg, source?.router.verifySsl),
        wirelessOnly,
        configurationUrl: overridesArg.router?.configurationUrl || source?.router.configurationUrl || (host ? `${ssl ? 'https' : 'http'}://${this.hostForUrl(host)}${this.defaultPort(ssl) === port ? '' : `:${port}`}/` : undefined),
        macAddress: overridesArg.router?.macAddress || this.normalizeMac(configArg.macAddress || configArg.mac) || source?.router.macAddress,
        manufacturer: overridesArg.router?.manufacturer || configArg.manufacturer || source?.router.manufacturer || ddwrtManufacturer,
        model: overridesArg.router?.model || configArg.model || source?.router.model || ddwrtDisplayName,
        available: overridesArg.router?.available ?? source?.router.available ?? connected,
        metadata: this.cleanAttributes({
          ...source?.router.metadata,
          ...configArg.metadata,
          ...overridesArg.router?.metadata,
          username: configArg.username,
        }),
      },
      clients,
      leases,
      sensors,
      rawStatus: this.cleanRawStatus({
        wireless: rawStatus.wireless,
        lan: rawStatus.lan,
        wirelessResponse: rawStatus.wirelessResponse || source?.rawStatus?.wirelessResponse,
        lanResponse: rawStatus.lanResponse || source?.rawStatus?.lanResponse,
      }),
      updatedAt,
      events: [...(source?.events || []), ...eventsArg, ...(overridesArg.events || [])],
      metadata: this.cleanAttributes({
        ...source?.metadata,
        ...configArg.metadata,
        ...overridesArg.metadata,
        upstreamPlatform: 'device_tracker',
        nativeHttpImplemented: true,
        nativeHttpEnabled: configArg.nativeHttpEnabled !== false,
        commandExecutorConfigured: Boolean(configArg.commandExecutor || configArg.transport?.execute || configArg.nativeClient?.execute || configArg.nativeClient?.sendCommand || configArg.nativeClient?.reboot),
      }),
      error: overridesArg.error || source?.error,
    };
  }

  public static mergeSnapshot(baseArg: IDdwrtSnapshot, patchArg: Partial<IDdwrtSnapshot>): IDdwrtSnapshot {
    return {
      ...baseArg,
      ...patchArg,
      router: { ...baseArg.router, ...patchArg.router, metadata: this.cleanAttributes({ ...baseArg.router.metadata, ...patchArg.router?.metadata }) },
      clients: patchArg.clients || baseArg.clients,
      leases: patchArg.leases || baseArg.leases,
      sensors: this.sensorMap({ ...baseArg.sensors, ...patchArg.sensors }),
      rawStatus: { ...baseArg.rawStatus, ...patchArg.rawStatus },
      events: [...baseArg.events, ...(patchArg.events || [])],
      metadata: this.cleanAttributes({ ...baseArg.metadata, ...patchArg.metadata }),
      updatedAt: patchArg.updatedAt || baseArg.updatedAt || new Date().toISOString(),
    };
  }

  public static toDevices(snapshotArg: IDdwrtSnapshot): plugins.shxInterfaces.data.IDeviceDefinition[] {
    const updatedAt = snapshotArg.updatedAt || new Date().toISOString();
    const devices: plugins.shxInterfaces.data.IDeviceDefinition[] = [{
      id: this.routerDeviceId(snapshotArg),
      integrationDomain: ddwrtDomain,
      name: snapshotArg.router.name || ddwrtDisplayName,
      protocol: 'http',
      manufacturer: snapshotArg.router.manufacturer || ddwrtManufacturer,
      model: snapshotArg.router.model || ddwrtDisplayName,
      online: snapshotArg.connected && snapshotArg.router.available !== false,
      features: [
        { id: 'connection', capability: 'sensor', name: 'Connection', readable: true, writable: false },
        { id: 'tracked_clients', capability: 'sensor', name: 'Tracked clients', readable: true, writable: false },
        { id: 'active_wireless_clients', capability: 'sensor', name: 'Active wireless clients', readable: true, writable: false },
        { id: 'active_lan_clients', capability: 'sensor', name: 'Active LAN clients', readable: true, writable: false },
        { id: 'dhcp_leases', capability: 'sensor', name: 'DHCP leases', readable: true, writable: false },
      ],
      state: [
        { featureId: 'connection', value: snapshotArg.connected ? 'online' : 'offline', updatedAt },
        { featureId: 'tracked_clients', value: this.deviceStateValue(snapshotArg.sensors.tracked_clients), updatedAt },
        { featureId: 'active_wireless_clients', value: this.deviceStateValue(snapshotArg.sensors.active_wireless_clients), updatedAt },
        { featureId: 'active_lan_clients', value: this.deviceStateValue(snapshotArg.sensors.active_lan_clients), updatedAt },
        { featureId: 'dhcp_leases', value: this.deviceStateValue(snapshotArg.sensors.dhcp_leases), updatedAt },
      ],
      metadata: this.cleanAttributes({
        attribution: ddwrtAttribution,
        host: snapshotArg.router.host,
        port: snapshotArg.router.port,
        ssl: snapshotArg.router.ssl,
        verifySsl: snapshotArg.router.verifySsl,
        wirelessOnly: snapshotArg.router.wirelessOnly,
        configurationUrl: snapshotArg.router.configurationUrl,
        source: snapshotArg.source,
        error: snapshotArg.error,
        ...snapshotArg.metadata,
      }),
    }];

    for (const client of snapshotArg.clients) {
      devices.push({
        id: this.clientDeviceId(client),
        integrationDomain: ddwrtDomain,
        name: this.clientName(client),
        protocol: 'unknown',
        online: snapshotArg.connected && client.active,
        features: [{ id: 'connected', capability: 'sensor', name: 'Connected', readable: true, writable: false }],
        state: [{ featureId: 'connected', value: client.active, updatedAt }],
        metadata: this.cleanAttributes({
          attribution: ddwrtAttribution,
          nativePlatform: 'device_tracker',
          macAddress: client.macAddress,
          ipAddress: client.ipAddress,
          hostname: client.hostname,
          source: client.source,
          wireless: client.wireless,
        }),
      });
    }
    return devices;
  }

  public static toEntities(snapshotArg: IDdwrtSnapshot): IIntegrationEntity[] {
    const usedIds = new Map<string, number>();
    const routerId = this.routerDeviceId(snapshotArg);
    const baseName = snapshotArg.router.name || ddwrtDisplayName;
    const entities: IIntegrationEntity[] = [
      this.entity('binary_sensor', `${baseName} Connected`, routerId, `${this.uniqueBase(snapshotArg)}_connected`, snapshotArg.connected ? 'on' : 'off', usedIds, { deviceClass: 'connectivity', nativeType: 'router_connected' }, true),
      this.entity('sensor', `${baseName} Tracked Clients`, routerId, `${this.uniqueBase(snapshotArg)}_tracked_clients`, snapshotArg.sensors.tracked_clients ?? 0, usedIds, { nativeType: 'tracked_clients', stateClass: 'measurement' }, snapshotArg.connected),
      this.entity('sensor', `${baseName} Active Wireless Clients`, routerId, `${this.uniqueBase(snapshotArg)}_active_wireless_clients`, snapshotArg.sensors.active_wireless_clients ?? 0, usedIds, { nativeType: 'active_wireless_clients', stateClass: 'measurement' }, snapshotArg.connected),
      this.entity('sensor', `${baseName} Active LAN Clients`, routerId, `${this.uniqueBase(snapshotArg)}_active_lan_clients`, snapshotArg.sensors.active_lan_clients ?? 0, usedIds, { nativeType: 'active_lan_clients', stateClass: 'measurement' }, snapshotArg.connected),
      this.entity('sensor', `${baseName} DHCP Leases`, routerId, `${this.uniqueBase(snapshotArg)}_dhcp_leases`, snapshotArg.sensors.dhcp_leases ?? 0, usedIds, { nativeType: 'dhcp_leases', stateClass: 'measurement' }, snapshotArg.connected),
    ];

    for (const client of snapshotArg.clients) {
      entities.push(this.entity('binary_sensor', `${this.clientName(client)} Connected`, this.clientDeviceId(client), `${this.slug(client.macAddress || this.clientName(client))}_connected`, client.active ? 'on' : 'off', usedIds, {
        deviceClass: 'connectivity',
        nativePlatform: 'device_tracker',
        mac: client.macAddress,
        macAddress: client.macAddress,
        ipAddress: client.ipAddress,
        hostname: client.hostname,
        source: client.source,
        wireless: client.wireless,
        interface: client.interface,
        ...client.metadata,
      }, snapshotArg.connected));
    }
    return entities;
  }

  public static commandForService(snapshotArg: IDdwrtSnapshot, requestArg: IServiceCallRequest): IDdwrtCommand | undefined {
    const target = requestArg.target || {};
    const routerDeviceId = this.routerDeviceId(snapshotArg);
    const targetMatchesRouter = !target.deviceId || target.deviceId === routerDeviceId;
    if (requestArg.domain === ddwrtDomain && requestArg.service === 'reboot' && targetMatchesRouter) {
      return {
        action: 'reboot',
        method: 'executor',
        service: requestArg.service,
        target,
        data: requestArg.data,
        deviceId: routerDeviceId,
        host: snapshotArg.router.host,
        transmitted: false,
        metadata: this.cleanAttributes({ configurationUrl: snapshotArg.router.configurationUrl }),
      };
    }
    return undefined;
  }

  public static toIntegrationEvent(eventArg: IDdwrtEvent): IIntegrationEvent {
    return {
      type: eventArg.type === 'command_failed' ? 'error' : 'state_changed',
      integrationDomain: ddwrtDomain,
      deviceId: eventArg.deviceId,
      entityId: eventArg.entityId,
      data: eventArg,
      timestamp: eventArg.timestamp || Date.now(),
    };
  }

  public static routerDeviceId(snapshotArg: IDdwrtSnapshot): string {
    return `${ddwrtDomain}.router.${this.uniqueBase(snapshotArg)}`;
  }

  public static clientDeviceId(clientArg: IDdwrtClientDevice): string {
    return `${ddwrtDomain}.client.${this.slug(clientArg.macAddress || clientArg.id || clientArg.name || 'client')}`;
  }

  public static normalizeMac(valueArg: unknown): string | undefined {
    if (typeof valueArg !== 'string') {
      return undefined;
    }
    const directMatch = valueArg.match(macRegex)?.[0] || valueArg;
    const compact = directMatch.replace(/[^0-9a-f]/gi, '').toLowerCase();
    return compact.length === 12 ? compact.match(/.{1,2}/g)?.join(':') : undefined;
  }

  public static slug(valueArg: unknown): string {
    const slug = String(valueArg || '').trim().toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_+|_+$/g, '');
    return slug || ddwrtDomain;
  }

  public static cleanAttributes<TValue extends Record<string, unknown>>(valueArg: TValue): TValue {
    const result: Record<string, unknown> = {};
    for (const [key, value] of Object.entries(valueArg)) {
      if (value !== undefined) {
        result[key] = value;
      }
    }
    return result as TValue;
  }

  private static rawStatus(configArg: IDdwrtConfig, overridesArg: Partial<IDdwrtSnapshot>, sourceArg?: IDdwrtSnapshot): IDdwrtRawStatusSet {
    const wirelessResponse = overridesArg.rawStatus?.wirelessResponse || configArg.wirelessResponse || configArg.rawStatus?.wirelessResponse || sourceArg?.rawStatus?.wirelessResponse;
    const lanResponse = overridesArg.rawStatus?.lanResponse || configArg.lanResponse || configArg.rawStatus?.lanResponse || sourceArg?.rawStatus?.lanResponse;
    return {
      wireless: overridesArg.rawStatus?.wireless
        || this.toStatusData(configArg.wirelessStatus)
        || configArg.rawStatus?.wireless
        || this.toStatusData(wirelessResponse)
        || sourceArg?.rawStatus?.wireless,
      lan: overridesArg.rawStatus?.lan
        || this.toStatusData(configArg.lanStatus)
        || configArg.rawStatus?.lan
        || this.toStatusData(lanResponse)
        || sourceArg?.rawStatus?.lan,
      wirelessResponse,
      lanResponse,
    };
  }

  private static parseDhcpLeases(valueArg: string | undefined): IDdwrtDhcpLease[] {
    if (!valueArg) {
      return [];
    }
    const elements = this.splitDdwrtArray(valueArg);
    const leases: IDdwrtDhcpLease[] = [];
    const count = Math.floor(elements.length / 5);
    for (let index = 0; index < count; index++) {
      const base = index * 5;
      const macAddress = this.normalizeMac(elements[base + 2]);
      if (!macAddress) {
        continue;
      }
      const ipCandidate = elements[base + 1];
      leases.push(this.cleanAttributes({
        hostname: this.stringValue(elements[base]),
        ipAddress: ipv4Regex.test(ipCandidate || '') ? ipCandidate : undefined,
        macAddress,
        expires: this.stringValue(elements[base + 4]),
        raw: elements.slice(base, base + 5),
      }) as IDdwrtDhcpLease);
    }
    return leases;
  }

  private static parseActiveClients(valueArg: string | undefined, sourceArg: TDdwrtClientSource, leaseMapArg: Map<string, IDdwrtDhcpLease>): IDdwrtClientDevice[] {
    if (!valueArg) {
      return [];
    }
    const clients: IDdwrtClientDevice[] = [];
    const seen = new Set<string>();
    for (const element of this.splitDdwrtArray(valueArg)) {
      const macAddress = this.normalizeMac(element);
      if (!macAddress || seen.has(macAddress)) {
        continue;
      }
      seen.add(macAddress);
      const lease = leaseMapArg.get(macAddress);
      clients.push(this.cleanAttributes({
        id: macAddress,
        macAddress,
        name: lease?.hostname || macAddress,
        hostname: lease?.hostname,
        ipAddress: lease?.ipAddress,
        active: true,
        wireless: sourceArg === 'wireless',
        source: sourceArg,
        metadata: { rawElement: element },
      }) as IDdwrtClientDevice);
    }
    return clients;
  }

  private static splitDdwrtArray(valueArg: string): string[] {
    const trimmed = valueArg.trim().replace(/^\[|\]$/g, '');
    if (!trimmed) {
      return [];
    }
    const quoted = [...trimmed.matchAll(/'([^']*)'|"([^"]*)"/g)].map((matchArg) => (matchArg[1] ?? matchArg[2] ?? '').trim());
    if (quoted.length) {
      return quoted.filter((itemArg) => itemArg.length > 0);
    }
    return trimmed.split(',').map((itemArg) => itemArg.trim().replace(/^['"]|['"]$/g, '')).filter((itemArg) => itemArg.length > 0);
  }

  private static mergeLeases(leasesArg: IDdwrtDhcpLease[]): IDdwrtDhcpLease[] {
    const byMac = new Map<string, IDdwrtDhcpLease>();
    for (const lease of leasesArg) {
      const macAddress = this.normalizeMac(lease.macAddress);
      if (!macAddress) {
        continue;
      }
      byMac.set(macAddress, this.cleanAttributes({ ...byMac.get(macAddress), ...lease, macAddress }) as IDdwrtDhcpLease);
    }
    return [...byMac.values()];
  }

  private static mergeClients(clientsArg: IDdwrtClientDevice[], wirelessOnlyArg: boolean, leaseMapArg: Map<string, IDdwrtDhcpLease>): IDdwrtClientDevice[] {
    const byMac = new Map<string, IDdwrtClientDevice>();
    for (const client of clientsArg) {
      const macAddress = this.normalizeMac(client.macAddress);
      if (!macAddress) {
        continue;
      }
      const lease = leaseMapArg.get(macAddress);
      const existing = byMac.get(macAddress);
      byMac.set(macAddress, this.cleanAttributes({
        ...existing,
        ...client,
        id: client.id || existing?.id || macAddress,
        macAddress,
        name: client.name || client.hostname || lease?.hostname || existing?.name || macAddress,
        hostname: client.hostname || lease?.hostname || existing?.hostname,
        ipAddress: client.ipAddress || lease?.ipAddress || existing?.ipAddress,
        active: client.active ?? existing?.active ?? true,
        wireless: client.wireless ?? existing?.wireless ?? wirelessOnlyArg,
      }) as IDdwrtClientDevice);
    }
    return [...byMac.values()];
  }

  private static entity(platformArg: IIntegrationEntity['platform'], nameArg: string, deviceIdArg: string, uniqueArg: string, stateArg: unknown, usedIdsArg: Map<string, number>, attributesArg: Record<string, unknown>, availableArg: boolean): IIntegrationEntity {
    const baseId = `${platformArg}.${this.slug(nameArg)}`;
    const idCount = usedIdsArg.get(baseId) || 0;
    usedIdsArg.set(baseId, idCount + 1);
    const id = idCount ? `${baseId}_${idCount + 1}` : baseId;
    return {
      id,
      uniqueId: `${ddwrtDomain}_${uniqueArg}`,
      integrationDomain: ddwrtDomain,
      deviceId: deviceIdArg,
      platform: platformArg,
      name: nameArg,
      state: stateArg,
      attributes: this.cleanAttributes({ attribution: ddwrtAttribution, ...attributesArg }),
      available: availableArg,
    };
  }

  private static sensorMap(valueArg: Record<string, unknown>): IDdwrtSensorMap {
    return this.cleanAttributes(valueArg) as IDdwrtSensorMap;
  }

  private static cleanRawStatus(valueArg: IDdwrtRawStatusSet): IDdwrtRawStatusSet | undefined {
    const result = this.cleanAttributes({
      wireless: valueArg.wireless,
      lan: valueArg.lan,
      wirelessResponse: valueArg.wirelessResponse,
      lanResponse: valueArg.lanResponse,
    }) as IDdwrtRawStatusSet;
    return Object.keys(result).length ? result : undefined;
  }

  private static uniqueBase(snapshotArg: IDdwrtSnapshot): string {
    return this.slug(snapshotArg.router.id || snapshotArg.router.macAddress || snapshotArg.router.host || snapshotArg.router.name || ddwrtDomain);
  }

  private static clientName(clientArg: IDdwrtClientDevice): string {
    return clientArg.name || clientArg.hostname || clientArg.macAddress;
  }

  private static host(configArg: IDdwrtConfig): string | undefined {
    return this.stringValue(configArg.host || configArg.ipAddress || configArg.address || configArg.ip);
  }

  private static hostForUrl(valueArg: string): string {
    if (/^[a-z][a-z0-9+.-]*:\/\//i.test(valueArg)) {
      try {
        return new URL(valueArg).host;
      } catch {
        return valueArg;
      }
    }
    return valueArg;
  }

  private static ssl(configArg: IDdwrtConfig, fallbackArg?: boolean): boolean {
    return configArg.ssl ?? configArg.useSsl ?? fallbackArg ?? ddwrtDefaultSsl;
  }

  private static verifySsl(configArg: IDdwrtConfig, fallbackArg?: boolean): boolean {
    return configArg.verifySsl ?? configArg.verify_ssl ?? fallbackArg ?? ddwrtDefaultVerifySsl;
  }

  private static wirelessOnly(configArg: IDdwrtConfig, fallbackArg?: boolean): boolean {
    return configArg.wirelessOnly ?? configArg.wireless_only ?? fallbackArg ?? ddwrtDefaultWirelessOnly;
  }

  private static defaultPort(sslArg: boolean): number {
    return sslArg ? ddwrtDefaultHttpsPort : ddwrtDefaultHttpPort;
  }

  private static stringValue(valueArg: unknown): string | undefined {
    if (typeof valueArg === 'string' && valueArg.trim()) {
      return valueArg.trim();
    }
    return undefined;
  }

  private static deviceStateValue(valueArg: unknown): plugins.shxInterfaces.data.TDeviceStateValue {
    if (valueArg === undefined || valueArg === null) {
      return null;
    }
    if (typeof valueArg === 'string' || typeof valueArg === 'number' || typeof valueArg === 'boolean') {
      return valueArg;
    }
    if (typeof valueArg === 'object' && !Array.isArray(valueArg)) {
      return valueArg as Record<string, unknown>;
    }
    return String(valueArg);
  }
}

export const parseDdwrtResponse = (dataArg: string): IDdwrtStatusData => DdwrtMapper.parseDdwrtResponse(dataArg);

export const normalizeDdwrtMac = (valueArg: unknown): string | undefined => DdwrtMapper.normalizeMac(valueArg);
