#ifndef KVFS_H
#define KVFS_H

#include <stdint.h>
#include <stddef.h>

#define VFS_FILE        0x01
#define VFS_DIRECTORY   0x02
#define VFS_CHARDEVICE  0x03
#define VFS_BLOCKDEVICE 0x04
#define VFS_PIPE        0x05

struct vfs_node;

typedef uint32_t (*read_type_t)(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer);
typedef uint32_t (*write_type_t)(struct vfs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer);
typedef uint32_t (*seek_type_t)(struct vfs_node* node, uint32_t offset, int whence);
typedef struct vfs_node* (*finddir_type_t)(struct vfs_node* node, const char* name);
typedef struct vfs_node* (*mkdir_type_t)(struct vfs_node* node, const char* name);
typedef struct vfs_node* (*create_type_t)(struct vfs_node* node, const char* name);

typedef struct vfs_node {
    char name[128];
    uint32_t flags;       // File, directory, device, etc.
    uint32_t size;        // Size of file in bytes

    struct vfs_node* first_child;
    struct vfs_node* next_sibling;
    
    read_type_t read;
    write_type_t write;
    finddir_type_t find; 
    mkdir_type_t mkdir;
    create_type_t create;
    seek_type_t seek;

    struct vfs_node* mnt;
    void* data;
} vfs_node_t;

typedef struct {
    vfs_node_t* node;   // The actual CPIO/VFS node
    uint32_t offset;    // Current read/write cursor position
    uint32_t flags;     // Permissions (O_RDONLY, etc.)
} file_t;

vfs_node_t* vfs_create_root();
vfs_node_t* vfs_mkdir(vfs_node_t* parent, const char* name);

vfs_node_t* vfs_find(const char* path);

void vfs_mount(vfs_node_t* _mnt, vfs_node_t* _fs);
int vfs_open(const char* path, int flags);
int vfs_read(int fd, void* buf, size_t sz);

int vfs_seek(int fd, size_t offset);

int alloc_fd(file_t* f);

#endif