#pragma once
#include <stdint.h>
#include <sys/types.h>

#define TAR_MAGIC "ustar"
#define TAR_BLOCKSIZE 512

namespace InitRD
{
    struct TarHeader
    {                       /* byte offset */
        char name[100];     /*   0 */
        char mode[8];       /* 100 */
        char uid[8];        /* 108 */
        char gid[8];        /* 116 */
        char size[12];      /* 124 */
        char mtime[12];     /* 136 */
        char chksum[8];     /* 148 */
        char typeflag;      /* 156 */
        char linkname[100]; /* 157 */
        char magic[6];      /* 257 */
        char version[2];    /* 263 */
        char uname[32];     /* 265 */
        char gname[32];     /* 297 */
        char devmajor[8];   /* 329 */
        char devminor[8];   /* 337 */
        char prefix[155];   /* 345 */
                            /* 500 */
    } __attribute__((packed));

    struct File
    {
        char name[100];
        uint64_t size;
        uint64_t size_in_blocks;
        void* addr;
        mode_t mode;
    };

    uint64_t get_total_blocks();
    File get_file(TarHeader* header);
    void free_file(File& file);
    TarHeader* get_block(uint64_t block_index);
    bool is_valid_header(TarHeader* header);

    uint64_t get_file_physical_address(File& file);

    File open(const char* filename);
    void for_each(void (*callback)(File& file));

    bool is_initialized();

    void init();
}