#ifndef _KERNEL_FS_DEVFS_DEVFS_H
#define _KERNEL_FS_DEVFS_DEVFS_H

#include <fs/vfs.h>
#include <libkern/c_attrs.h>
#include <libkern/kassert.h>
#include <libkern/types.h>

#define DEVFS_INODE_LEN (sizeof(struct devfs_inode))
struct PACKED devfs_inode {
    mode_t mode;
    uint16_t uid;
    uint32_t size;
    uint32_t atime;
    uint32_t ctime;
    uint32_t mtime;
    uint32_t dtime;
    uint16_t gid;
    uint16_t links_count;
    uint32_t blocks;
    uint32_t flags;
    uint32_t osd1;

    /* NOTE: Instead of blocks here, we store devfs required things */
    uint32_t index;
    uint32_t dev_id;
    struct file_ops* handlers;
    struct devfs_inode* parent;
    struct devfs_inode* prev;
    struct devfs_inode* next;
    struct devfs_inode* first;
    struct devfs_inode* last;
#ifdef BITS32
    char* name;
    uint8_t padding[24];
#else // BITS64
    uint8_t padding[4];
#endif
    /* Block hack ends here */

    uint32_t generation;
    uint32_t file_acl;
    uint32_t dir_acl;
    uint32_t faddr;
#ifdef BITS32
    uint32_t osd2[3];
#else // BITS64
    char* name;
    uint32_t osd2[1];
#endif
};
typedef struct devfs_inode devfs_inode_t;
STATIC_ASSERT(DEVFS_INODE_LEN == INODE_LEN, devfs_inode);

void devfs_install();
int devfs_mount();

devfs_inode_t* devfs_mkdir(const path_t* vfspath, const char* name, size_t len);
devfs_inode_t* devfs_register(const path_t* vfspath, dev_t devid, const char* name, size_t len, mode_t mode, const file_ops_t* handlers);

#endif /* _KERNEL_FS_DEVFS_DEVFS_H */