import type { PingStats } from "./types";

export type PingPlatform = "darwin" | "linux" | "win32" | NodeJS.Platform;

export function parsePingOutput(stdout: string, platform: PingPlatform): null | PingStats {
  return platform === "win32" ? parseWindowsOutput(stdout) : parseUnixOutput(stdout);
}

function parseUnixOutput(stdout: string): null | PingStats {
  const packetMatch =
    /(\d+)\s+packets?\s+transmitted.*?(\d+)\s+(?:packets?\s+)?received.*?(\d+(?:\.\d+)?)%\s+packet\s+loss/i.exec(
      stdout,
    );
  if (!packetMatch) return null;

  const transmitted = Number(packetMatch[1]);
  const received = Number(packetMatch[2]);
  const packetLoss = Number(packetMatch[3]);
  const latencyMatch = /(?:rtt|round-trip).*?=\s*([\d.]+)\/([\d.]+)\/([\d.]+)/i.exec(stdout);

  return {
    alive: received > 0,
    avgLatencyMs: latencyMatch ? Number(latencyMatch[2]) : null,
    maxLatencyMs: latencyMatch ? Number(latencyMatch[3]) : null,
    minLatencyMs: latencyMatch ? Number(latencyMatch[1]) : null,
    packetLoss,
    received,
    transmitted,
  };
}

function parseWindowsOutput(stdout: string): null | PingStats {
  const packetMatch = /=\s*(\d+).*?=\s*(\d+).*?=\s*(\d+).*?(\d+(?:\.\d+)?)%/s.exec(stdout);
  if (!packetMatch) return null;

  const transmitted = Number(packetMatch[1]);
  const received = Number(packetMatch[2]);
  const packetLoss = Number(packetMatch[4]);
  const latencyMatch = /=\s*(\d+)ms.*?=\s*(\d+)ms.*?=\s*(\d+)ms/s.exec(stdout);

  return {
    alive: received > 0,
    avgLatencyMs: latencyMatch ? Number(latencyMatch[3]) : null,
    maxLatencyMs: latencyMatch ? Number(latencyMatch[2]) : null,
    minLatencyMs: latencyMatch ? Number(latencyMatch[1]) : null,
    packetLoss,
    received,
    transmitted,
  };
}
