#pragma once
#include "uefi.h"

#define FS_BLOCK_SIZE   512
#define FS_TOTAL_BLOCKS 8192
#define FS_MAGIC        0x50524953  /* "PRIS" */
#define FS_MAX_NAME     24
#define FS_MAX_PATH     128
#define FS_DIRECT_BLOCKS 10
#define FS_INODE_SIZE   128
#define FS_DIR_ENTRY_SIZE 32

/* Типы */
#define FS_TYPE_FREE  0
#define FS_TYPE_FILE  1
#define FS_TYPE_DIR   2

/* Inode */
struct fs_inode {
    uint16_t mode;
    uint32_t size;
    uint32_t direct[FS_DIRECT_BLOCKS];
    uint32_t indirect;
    uint32_t parent;
    uint8_t  _pad[FS_INODE_SIZE - 2 - 4 - FS_DIRECT_BLOCKS*4 - 4 - 4];
};

/* Запись в директории */
struct fs_dirent {
    char     name[FS_MAX_NAME];
    uint32_t inode;
    uint8_t  type;
    uint8_t  _pad[FS_DIR_ENTRY_SIZE - FS_MAX_NAME - 4 - 1];
};

/* Superblock */
struct fs_super {
    uint32_t magic;
    uint32_t total_blocks;
    uint32_t free_blocks;
    uint32_t root_inode;
    uint32_t inode_count;
    uint32_t data_start;
};

void     fs_init(void);
uint32_t fs_alloc_block(void);
void     fs_free_block(uint32_t block);
int      fs_create(const char *name, uint8_t type, uint32_t parent);
int      fs_unlink(const char *name, uint32_t parent);
int      fs_find(const char *name, uint32_t parent);
int      fs_write(uint32_t inode, const void *data, uint32_t size);
int      fs_read(uint32_t inode, void *buf, uint32_t size, uint32_t offset);
int      fs_get_path(uint32_t inode, char *buf, int max);
int      fs_stat(uint32_t inode, char *name_out, uint8_t *type_out, uint32_t *size_out);
uint32_t fs_get_current(void);
void     fs_set_current(uint32_t inum);
uint32_t fs_get_parent(uint32_t inum);
uint32_t fs_get_direct(uint32_t inum, int idx);
uint32_t fs_get_size(uint32_t inum);
uint8_t  fs_get_mode(uint32_t inum);
void    *fs_data_block(uint32_t block);
uint32_t fs_total_blocks(void);
uint32_t fs_free_blocks(void);
