#include "resource.h"
#include "arena.h"
#include "tar.h"
#include "incbin.h"

#if RESOURCES_EMBEDDED

#include "inc.h"

/* Add resource data to binary */

GLOBAL struct {
    struct arena arena;
    struct tar_archive archive;
} G = { 0 }, DEBUG_ALIAS(G, G_resource);
#endif

struct resource_startup_receipt resource_startup(void)
{
#if RESOURCES_EMBEDDED
    struct buffer embedded_data = inc_res_tar();
    G.arena = arena_alloc(GIGABYTE(64));
    if (embedded_data.size <= 0) {
        sys_panic(STR("No embedded resources found"));
    }
    G.archive = tar_parse(&G.arena, embedded_data, STR("res/"));
#else
    /* Ensure we have the right working directory */
    if (!sys_is_dir(STR("res"))) {
        sys_panic(STR("Resource directory \"res\" not found"));
    }
#endif

    return (struct resource_startup_receipt) { 0 };
}

b32 resource_exists(struct string path)
{
    __prof;
#if RESOURCES_EMBEDDED
    struct tar_entry *entry = tar_get(&G.archive, path);
    return entry && !entry->is_dir;
#else
    return sys_is_file(path);
#endif
}

struct resource resource_open(struct string path)
{
    __prof;
#if RESOURCES_EMBEDDED
    struct tar_entry *entry = tar_get(&G.archive, path);
    return (struct resource) {
        .bytes = entry ? entry->buff : BUFFER(0, 0)
    };
#else
    struct sys_file file = sys_file_open_read_wait(path);
    struct sys_file_map file_map = sys_file_map_open_read(file);
    struct buffer bytes = sys_file_map_data(file_map);
    return (struct resource) {
        .bytes = bytes,
        .file = file,
        .file_map = file_map
    };
#endif
}

#if !RESOURCES_EMBEDDED
void resource_close(struct resource res)
{
    sys_file_map_close(res.file_map);
    sys_file_close(res.file);
}
#endif
