const MAGIC_METRIC_NULL = -2;
function formatBits(bits, decimals = 2) {
  if (bits <= 0 || bits === MAGIC_METRIC_NULL) {
    return {
      value: 0,
      unit: "b"
    };
  }
  const k = 1e3;
  const units = ["b", "Kb", "Mb", "Gb", "Tb", "Pb"];
  let i = Math.floor(Math.log(bits) / Math.log(k));
  i = i < 0 ? 0 : i > units.length - 1 ? units.length - 1 : i;
  return {
    value: parseFloat((bits / Math.pow(k, i)).toFixed(decimals)),
    unit: units[i]
  };
}
function formatFrequency(frequency, decimals = 2) {
  if (frequency <= 0 || frequency === MAGIC_METRIC_NULL) {
    return {
      value: 0,
      unit: "Hz"
    };
  }
  const k = 1e3;
  const units = ["Hz", "KHz", "MHz", "GHz", "THz"];
  let i = Math.floor(Math.log(frequency) / Math.log(k));
  i = i < 0 ? 0 : i > units.length - 1 ? units.length - 1 : i;
  return {
    value: parseFloat((frequency / Math.pow(k, i)).toFixed(decimals)),
    unit: units[i]
  };
}
const SECOND = 1;
const MINUTE = 60 * SECOND;
const HOUR = 60 * MINUTE;
const DAY = 24 * HOUR;
const WEEK = 7 * DAY;
function formatSeconds(seconds, decimals = 0) {
  if (seconds <= MAGIC_METRIC_NULL) {
    seconds = 0;
  }
  const units = [
    {
      value: WEEK,
      unit: "week"
    },
    {
      value: DAY,
      unit: "day"
    },
    {
      value: HOUR,
      unit: "hour"
    },
    {
      value: MINUTE,
      unit: "minute"
    },
    {
      value: SECOND,
      unit: "second"
    }
  ];
  for (const unit of units) {
    if (seconds > unit.value) {
      return {
        value: parseFloat((seconds / unit.value).toFixed(decimals)),
        unit: unit.unit
      };
    }
  }
  return {
    value: parseFloat((seconds / SECOND).toFixed(decimals)),
    unit: "second"
  };
}
function formatBitPerSecond(input, decimals = 1) {
  if (input <= 0 || input === MAGIC_METRIC_NULL) {
    return {
      value: 0,
      unit: "bps"
    };
  }
  const k = 1e3;
  const units = ["bps", "Kbps", "Mbps", "Gbps", "Tbps"];
  let i = Math.floor(Math.log(input) / Math.log(k));
  i = i < 0 ? 0 : i > units.length - 1 ? units.length - 1 : i;
  return {
    value: parseFloat((input / Math.pow(k, i)).toFixed(decimals)),
    unit: units[i]
  };
}
function formatBps(input, decimals = 1) {
  if (input <= 0 || input === MAGIC_METRIC_NULL) {
    return {
      value: 0,
      unit: "Bps"
    };
  }
  const k = 1e3;
  const units = ["Bps", "KBps", "MBps", "GBps", "TBps"];
  let i = Math.floor(Math.log(input) / Math.log(k));
  i = i < 0 ? 0 : i > units.length - 1 ? units.length - 1 : i;
  return {
    value: parseFloat((input / Math.pow(k, i)).toFixed(decimals)),
    unit: units[i]
  };
}
function formatBytes(bytes, decimals = 2) {
  if (bytes <= 0 || bytes === MAGIC_METRIC_NULL) {
    return {
      value: 0,
      unit: "B"
    };
  }
  const k = 1024;
  const units = ["B", "KiB", "MiB", "GiB", "TiB", "PiB"];
  let i = Math.floor(Math.log(bytes) / Math.log(k));
  i = i < 0 ? 0 : i > units.length - 1 ? units.length - 1 : i;
  return {
    value: parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)),
    unit: units[i]
  };
}
function formatBytePerSecond(bytes, decimals = 2) {
  if (bytes <= 0 || bytes === MAGIC_METRIC_NULL) {
    return {
      value: 0,
      unit: "B/s"
    };
  }
  const k = 1024;
  const units = ["B/s", "KiB/s", "MiB/s", "GiB/s", "TiB/s", "PiB/s"];
  let i = Math.floor(Math.log(bytes) / Math.log(k));
  i = i < 0 ? 0 : i > units.length - 1 ? units.length - 1 : i;
  return {
    value: parseFloat((bytes / Math.pow(k, i)).toFixed(decimals)),
    unit: units[i]
  };
}
function formatPercent(input, decimals = 2, saturated = true) {
  if (input === MAGIC_METRIC_NULL) {
    input = 0;
  }
  if (saturated) {
    if (input <= 0) {
      input = 0;
    }
    if (input > 100) {
      input = 100;
    }
  }
  const value = input.toFixed(decimals);
  if (parseFloat(value) === 0 && input > 0) {
    if (decimals >= 1) {
      return {
        value: `0.${"0".repeat(decimals - 1)}1`,
        numberValue: parseFloat(`0.${"0".repeat(decimals - 1)}1`),
        unit: "%"
      };
    }
    return {
      value: "1",
      numberValue: 1,
      unit: "%"
    };
  }
  return {
    value,
    numberValue: parseFloat(input.toFixed(decimals)),
    unit: "%"
  };
}
function formatSpeed(input, decimals = 0) {
  input /= 1e3;
  if (input < 1)
    return { value: "-", unit: "" };
  const units = ["KbE", "MbE", "GbE", "TbE"];
  const k = 1e3;
  let i = Math.floor(Math.log(input) / Math.log(k));
  i = i < 0 ? 0 : i > units.length - 1 ? units.length - 1 : i;
  return {
    value: parseFloat((input / Math.pow(k, i)).toFixed(decimals)),
    unit: units[i]
  };
}
const K = 1e3;
function formatCount(input) {
  if (input === MAGIC_METRIC_NULL) {
    input = 0;
  }
  const units = ["", "K", "M", "G", "T", "P"];
  let i = Math.floor(Math.log(input || 1) / Math.log(K));
  i = i < 0 ? 0 : i > units.length - 1 ? units.length - 1 : i;
  return {
    value: parseFloat((input / Math.pow(K, i)).toFixed(2)),
    unit: units[i]
  };
}
function formatNanoSecond(input) {
  if (input <= 0 || input === MAGIC_METRIC_NULL) {
    return {
      value: 0,
      unit: ""
    };
  }
  const units = ["ns", "\u03BCs", "ms", "s", "min", "h", "day"];
  const divider = [1e3, 1e3, 1e3, 60, 60, 24];
  let multiplier = 1;
  for (let i = 0; i < divider.length; i++) {
    if (input < multiplier * divider[i]) {
      return {
        value: parseFloat((input / multiplier).toFixed(2)),
        unit: units[i]
      };
    }
    multiplier *= divider[i];
  }
  return {
    value: parseFloat((input / multiplier).toFixed(2)),
    unit: "day"
  };
}
function formatTemperature(input, decimals = 2) {
  if (input === MAGIC_METRIC_NULL) {
    input = 0;
  }
  return {
    value: parseFloat(input.toFixed(decimals)),
    unit: "\u2103"
  };
}
const unitRules = [
  {
    divider: [1e3, 1e3, 1e3, 1e3, 1e3, 1e3],
    unit: ["", "K", "M", "G", "T", "P"]
  },
  {
    divider: [1e3, 1e3, 1e3, 1e3, 1e3, 1e3],
    unit: ["bps", "Kbps", "Mbps", "Gbps", "Tbps", "Pbps"]
  },
  {
    divider: [1e3, 1e3, 1e3, 1e3, 1e3, 1e3],
    unit: ["Bps", "KBps", "MBps", "GBps", "TBps", "PBps"]
  },
  {
    divider: [1024, 1024, 1024, 1024, 1024, 1024],
    unit: ["B", "KiB", "MiB", "GiB", "TiB", "PiB"]
  },
  {
    divider: [1024, 1024, 1024, 1024, 1024, 1024],
    unit: ["B/s", "KiB/s", "MiB/s", "GiB/s", "TiB/s", "PiB/s"]
  },
  {
    divider: [1e3, 1e3, 1e3, 60, 60, 24],
    unit: ["ns", "\u03BCs", "ms", "s", "min", "h"]
  },
  {
    divider: [1e3, 1e3, 1e3, 1e3, 1e3],
    unit: ["Hz", "KHz", "MHz", "GHz", "THz"]
  }
];

export { DAY, HOUR, K, MAGIC_METRIC_NULL, MINUTE, SECOND, WEEK, formatBitPerSecond, formatBits, formatBps, formatBytePerSecond, formatBytes, formatCount, formatFrequency, formatNanoSecond, formatPercent, formatSeconds, formatSpeed, formatTemperature, unitRules };
