#include "zvfs_path_entry.h"
#include "zvfs.h"

#include <stdlib.h>
#include <string.h>
#include <errno.h>

/* ------------------------------------------------------------------ */
/* internal helper                                                      */
/* ------------------------------------------------------------------ */

static struct zvfs_path_entry *_path_find(const char *path)
{
    struct zvfs_path_entry *e = NULL;
    HASH_FIND_STR(g_fs.path_cache, path, e);
    return e;
}

/* ------------------------------------------------------------------ */
/* public API  （调用方持有 g_fs.path_mu）                              */
/* ------------------------------------------------------------------ */

int path_cache_insert(const char *path, struct zvfs_inode *inode)
{
    if (_path_find(path))
        return -EEXIST;

    struct zvfs_path_entry *e = calloc(1, sizeof(*e));
    if (!e)
        return -ENOMEM;

    e->path  = strdup(path);
    if (!e->path) {
        free(e);
        return -ENOMEM;
    }
    e->inode = inode;

    HASH_ADD_STR(g_fs.path_cache, path, e);
    return 0;
}

struct zvfs_path_entry *path_cache_lookup(const char *path)
{
    return _path_find(path);
}

void path_cache_remove(const char *path)
{
    struct zvfs_path_entry *e = _path_find(path);
    if (!e)
        return;
    HASH_DEL(g_fs.path_cache, e);
    free(e->path);
    free(e);
}

int path_cache_rename(const char *old_path, const char *new_path)
{
    struct zvfs_path_entry *old_e = _path_find(old_path);
    if (!old_e)
        return -1;

    /* 若 new_path 已存在，先清掉旧 entry（inode 引用由上层处理） */
    struct zvfs_path_entry *new_e = _path_find(new_path);
    if (new_e) {
        HASH_DEL(g_fs.path_cache, new_e);
        free(new_e->path);
        free(new_e);
    }

    /* 替换 key：从表中删除，修改 key 字符串，重新插入 */
    HASH_DEL(g_fs.path_cache, old_e);
    free(old_e->path);
    old_e->path = strdup(new_path);
    if (!old_e->path) {
        free(old_e);
        return -1;
    }
    HASH_ADD_STR(g_fs.path_cache, path, old_e);
    return 0;
}