#include <stdint.h>
#include <stddef.h>
#include "kprintf.h"
#include "util.h"

char *util_get_filename(char *path) {
  char *lastslash = path;
  char *p = path;

  while (*p) {
    if (*p == '/') {
      lastslash = p + 1;
    }
    p++;
  }
  return lastslash;
}

const char *human_size(uint64_t bytes, char *buf, size_t bufsize) {
  static const char *units[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB" };
  int unit = 0;

  // Scale down until value fits nicely
  uint64_t rem = 0;
  while (bytes >= 1024 && unit < (int)(sizeof(units)/sizeof(units[0])) - 1) {
    rem = bytes % 1024;
    bytes /= 1024;
    unit++;
  }

  if (unit == 0) {
    // Just bytes
    ksnprintf(buf, bufsize, "%llu %s", (unsigned long long)bytes, units[unit]);
  } else {
    // Show one decimal place without using floats
    // Multiply remainder by 10 to get first decimal digit
    uint64_t frac = (rem * 10 + 512) / 1024; // rounded
    if (frac == 10) { // handle carry, e.g. 1023.9 -> 1024.0
      bytes++;
      frac = 0;
    }

    if (frac > 0) ksnprintf(buf, bufsize, "%llu.%llu %s", (unsigned long long)bytes, (unsigned long long)frac, units[unit]);
    else ksnprintf(buf, bufsize, "%llu %s", (unsigned long long)bytes, units[unit]);
  }

  return buf;
}
