#include <aux/compiler.h>
#include <libk/std.h>
#include <libk/string.h>
#include <limine/requests.h>
#include <rd/rd.h>
#include <sys/debug.h>

#define RD_FILES_MAX 64
#define RD_PATH      "/boot/mop3dist.tar"

static struct rd_file rd_files[RD_FILES_MAX];

struct rd_file* rd_get_file (char* filename) {
  for (size_t i = 0; i < RD_FILES_MAX; i++) {
    if ((rd_files[i].hdr != NULL) &&
        (memcmp (rd_files[i].hdr->filename, filename, strlen (filename)) == 0))
      return &rd_files[i];
  }
  return NULL;
}

static size_t rd_tar_get_size (uint8_t* in) {
  size_t size = 0;
  size_t j;
  size_t count = 1;

  for (j = 11; j > 0; j--, count *= 8)
    size += ((in[j - 1] - '0') * count);

  return size;
}

static size_t rd_tar_parse (uint8_t* addr) {
  size_t i;

  for (i = 0;; i++) {
    struct tar_hdr* hdr = (struct tar_hdr*)addr;

    if (hdr->filename[i] == '\0')
      break;

    size_t size = rd_tar_get_size (hdr->size);

    rd_files[i].hdr = hdr;
    rd_files[i].content = (uint8_t*)((uintptr_t)hdr + 512);
    rd_files[i].size = rd_tar_get_size ((uint8_t*)hdr->size);

    DEBUG ("filename=%s\n", hdr->filename);

    addr += ((size / 512) + 1) * 512;

    if (size % 512)
      addr += 512;
  }

  return i;
}

void rd_init (void) {
  struct limine_module_response* module = limine_module_request.response;

  uint8_t* rd_addr = NULL;

  for (size_t i = 0; i < module->module_count; i++) {
    struct limine_file* file = module->modules[i];
    DEBUG ("%s\n", file->path);

    if (memcmp (file->path, RD_PATH, strlen (RD_PATH)) == 0) {
      rd_addr = file->address;
    }
  }

  if (rd_addr == NULL) {
    DEBUG ("mop3dist.tar NOT FOUND!\n");

    for (;;)
      ;
  }

  rd_tar_parse (rd_addr);
}
