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

export function decodePayload(payload: string, encoding: UdpEncoding): Uint8Array {
  if (encoding === "hex") return hexToBytes(payload);
  if (encoding === "base64") return base64ToBytes(payload);
  return new TextEncoder().encode(payload);
}

export function encodeResponse(data: Uint8Array, encoding: UdpEncoding): string {
  if (encoding === "hex") return bytesToHex(data);
  if (encoding === "base64") return bytesToBase64(data);
  return new TextDecoder().decode(data);
}

function base64ToBytes(base64: string): Uint8Array {
  if (base64.length === 0) return new Uint8Array(0);
  const binary = atob(base64);
  const bytes = new Uint8Array(binary.length);
  for (let i = 0; i < binary.length; i++) {
    bytes[i] = binary.charCodeAt(i);
  }
  return bytes;
}

function bytesToBase64(data: Uint8Array): string {
  let binary = "";
  for (let i = 0; i < data.byteLength; i++) {
    binary += String.fromCharCode(data[i]!);
  }
  return btoa(binary);
}

function bytesToHex(data: Uint8Array): string {
  let hex = "";
  for (let i = 0; i < data.byteLength; i++) {
    hex += data[i]!.toString(16).padStart(2, "0");
  }
  return hex;
}

function hexToBytes(hex: string): Uint8Array {
  if (hex.length === 0) return new Uint8Array(0);
  if (hex.length % 2 !== 0) throw new Error("hex string must have even length");
  const bytes = new Uint8Array(hex.length / 2);
  for (let i = 0; i < hex.length; i += 2) {
    bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
  }
  return bytes;
}
