#ifndef __ZVFS_HOOK_INIT_H__
#define __ZVFS_HOOK_INIT_H__

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <stdarg.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include "fs/zvfs_sys_init.h"

/*
 * 所有原始函数指针集中在这里。
 * 命名规则：real_<funcname>
 * 通过 dlsym(RTLD_NEXT, "funcname") 在 __attribute__((constructor)) 中初始化。
 */

/* open 族 */
extern int   (*real_open)(const char *path, int flags, ...);
extern int   (*real_open64)(const char *path, int flags, ...);
extern int   (*real_openat)(int dirfd, const char *path, int flags, ...);
extern int   (*real_openat64)(int dirfd, const char *path, int flags, ...);
extern int   (*real_creat)(const char *path, mode_t mode);
extern int   (*real_creat64)(const char *path, mode_t mode);

/* close 族 */
extern int   (*real_close)(int fd);
extern int   (*real_close_range)(unsigned int first, unsigned int last, unsigned int flags);

/* dup 族 */
extern int   (*real_dup)(int oldfd);
extern int   (*real_dup2)(int oldfd, int newfd);
extern int   (*real_dup3)(int oldfd, int newfd, int flags);

/* read 族 */
extern ssize_t (*real_read)(int fd, void *buf, size_t count);
extern ssize_t (*real_pread)(int fd, void *buf, size_t count, off_t offset);
extern ssize_t (*real_pread64)(int fd, void *buf, size_t count, off64_t offset);
extern ssize_t (*real_readv)(int fd, const struct iovec *iov, int iovcnt);
extern ssize_t (*real_preadv)(int fd, const struct iovec *iov, int iovcnt, off_t offset);
extern ssize_t (*real_preadv64)(int fd, const struct iovec *iov, int iovcnt, off64_t offset);
extern ssize_t (*real_preadv2)(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags);

/* write 族 */
extern ssize_t (*real_write)(int fd, const void *buf, size_t count);
extern ssize_t (*real_pwrite)(int fd, const void *buf, size_t count, off_t offset);
extern ssize_t (*real_pwrite64)(int fd, const void *buf, size_t count, off64_t offset);
extern ssize_t (*real_writev)(int fd, const struct iovec *iov, int iovcnt);
extern ssize_t (*real_pwritev)(int fd, const struct iovec *iov, int iovcnt, off_t offset);
extern ssize_t (*real_pwritev64)(int fd, const struct iovec *iov, int iovcnt, off64_t offset);
extern ssize_t (*real_pwritev2)(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags);

/* lseek */
extern off_t   (*real_lseek)(int fd, off_t offset, int whence);
extern off64_t (*real_lseek64)(int fd, off64_t offset, int whence);

/* truncate / fallocate */
extern int   (*real_truncate)(const char *path, off_t length);
extern int   (*real_truncate64)(const char *path, off64_t length);
extern int   (*real_ftruncate)(int fd, off_t length);
extern int   (*real_ftruncate64)(int fd, off64_t length);
extern int   (*real_fallocate)(int fd, int mode, off_t offset, off_t len);
extern int   (*real_posix_fallocate)(int fd, off_t offset, off_t len);

/* stat 族 */
extern int   (*real_stat)(const char *path, struct stat *buf);
extern int   (*real_stat64)(const char *path, struct stat64 *buf);
extern int   (*real_fstat)(int fd, struct stat *buf);
extern int   (*real_fstat64)(int fd, struct stat64 *buf);
extern int   (*real_lstat)(const char *path, struct stat *buf);
extern int   (*real_lstat64)(const char *path, struct stat64 *buf);
extern int   (*real_fstatat)(int dirfd, const char *path, struct stat *buf, int flags);
extern int   (*real_fstatat64)(int dirfd, const char *path, struct stat64 *buf, int flags);
extern int   (*real_statx)(int dirfd, const char *path, int flags,
                            unsigned int mask, struct statx *buf);
/* glibc xstat fallback */
extern int   (*real___xstat)(int ver, const char *path, struct stat *buf);
extern int   (*real___xstat64)(int ver, const char *path, struct stat64 *buf);
extern int   (*real___fxstat)(int ver, int fd, struct stat *buf);
extern int   (*real___fxstat64)(int ver, int fd, struct stat64 *buf);
extern int   (*real___lxstat)(int ver, const char *path, struct stat *buf);
extern int   (*real___lxstat64)(int ver, const char *path, struct stat64 *buf);
extern int   (*real___fxstatat)(int ver, int dirfd, const char *path,
                                 struct stat *buf, int flags);
extern int   (*real___fxstatat64)(int ver, int dirfd, const char *path,
                                   struct stat64 *buf, int flags);

/* sync */
extern int   (*real_fsync)(int fd);
extern int   (*real_fdatasync)(int fd);
extern int   (*real_sync_file_range)(int fd, off64_t offset, off64_t nbytes, unsigned int flags);

/* fcntl / ioctl */
extern int   (*real_fcntl)(int fd, int cmd, ...);
extern int   (*real_fcntl64)(int fd, int cmd, ...);
extern int   (*real_ioctl)(int fd, unsigned long request, ...);

/* 目录感知 */
extern int   (*real_unlink)(const char *path);
extern int   (*real_unlinkat)(int dirfd, const char *path, int flags);
extern int   (*real_rename)(const char *oldpath, const char *newpath);
extern int   (*real_renameat)(int olddirfd, const char *oldpath,
                               int newdirfd, const char *newpath);
extern int   (*real_renameat2)(int olddirfd, const char *oldpath,
                                int newdirfd, const char *newpath,
                                unsigned int flags);

/* mmap 族（预留） */
extern void *(*real_mmap)(void *addr, size_t length, int prot, int flags,
                           int fd, off_t offset);
extern void *(*real_mmap64)(void *addr, size_t length, int prot, int flags,
                             int fd, off64_t offset);
extern int   (*real_munmap)(void *addr, size_t length);
extern int   (*real_msync)(void *addr, size_t length, int flags);

/* 进程 */
extern pid_t (*real_fork)(void);
extern pid_t (*real_vfork)(void);


/* glibc 内部别名 */
extern int     (*real___open)(const char *path, int flags, ...);
extern int     (*real___open64)(const char *path, int flags, ...);
extern int     (*real___libc_open)(const char *path, int flags, ...);
extern ssize_t (*real___read)(int fd, void *buf, size_t count);
extern ssize_t (*real___libc_read)(int fd, void *buf, size_t count);
extern ssize_t (*real___read_nocancel)(int fd, void *buf, size_t count);
extern ssize_t (*real___pread64)(int fd, void *buf, size_t count, off64_t offset);
extern ssize_t (*real___libc_pread)(int fd, void *buf, size_t count, off64_t offset);
extern ssize_t (*real___pread64_nocancel)(int fd, void *buf, size_t count, off64_t offset);
extern ssize_t (*real___read_chk)(int fd, void *buf, size_t count, size_t buflen);
extern ssize_t (*real___pread_chk)(int fd, void *buf, size_t count, off_t offset, size_t buflen);
extern ssize_t (*real___pread64_chk)(int fd, void *buf, size_t count, off64_t offset, size_t buflen);
extern ssize_t (*real___write)(int fd, const void *buf, size_t count);
extern ssize_t (*real___libc_write)(int fd, const void *buf, size_t count);
extern int     (*real___close)(int fd);
extern int     (*real___libc_close)(int fd);
extern size_t  (*real_fread_unlocked)(void *ptr, size_t size, size_t nmemb, FILE *stream);
extern size_t  (*real_fread)(void *ptr, size_t size, size_t nmemb, FILE *stream);
extern int     (*real_vfscanf)(FILE *stream, const char *format, va_list ap);
extern int     (*real___isoc99_vfscanf)(FILE *stream, const char *format, va_list ap);
extern FILE   *(*real_fopen)(const char *path, const char *mode);
extern FILE   *(*real_fopen64)(const char *path, const char *mode);
extern FILE   *(*real_fdopen)(int fd, const char *mode);

/* 初始化所有 real_* 指针，在 constructor 中调用 */
void zvfs_hook_init(void);

/* 判断路径 / fd 是否属于 zvfs 接管范围 */
int zvfs_is_zvfs_path(const char *path);
int zvfs_is_zvfs_fd(int fd);

/*
 * 将 dirfd + 相对路径解析为绝对路径，写入 buf（长度 bufsz）。
 * dirfd == AT_FDCWD 时等价于以当前工作目录为基准。
 * 成功返回 0，失败返回 -1 并设置 errno。
 */
int zvfs_resolve_atpath(int dirfd, const char *path, char *buf, size_t bufsz);

/* stat wrapper（优先 real_*，fallback 到 __xstat*） */
int zvfs_real_stat(const char *path, struct stat *buf);
int zvfs_real_stat64(const char *path, struct stat64 *buf);
int zvfs_real_fstat(int fd, struct stat *buf);
int zvfs_real_fstat64(int fd, struct stat64 *buf);
int zvfs_real_lstat(const char *path, struct stat *buf);
int zvfs_real_lstat64(const char *path, struct stat64 *buf);
int zvfs_real_fstatat(int dirfd, const char *path, struct stat *buf, int flags);
int zvfs_real_fstatat64(int dirfd, const char *path, struct stat64 *buf, int flags);
#endif // __ZVFS_HOOK_INIT_H__
