#ifndef __IPC_PROTO_H__
#define __IPC_PROTO_H__

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

#ifdef __cplusplus
extern "C" {
#endif

struct zvfs_conn;
struct zvfs_blob_handle;

enum zvfs_opcode {
    ZVFS_OP_CREATE = 1,
    ZVFS_OP_OPEN,
    ZVFS_OP_READ,
    ZVFS_OP_WRITE,
    ZVFS_OP_RESIZE,
    ZVFS_OP_SYNC_MD,
    ZVFS_OP_CLOSE,
    ZVFS_OP_DELETE,
    ZVFS_OP_ADD_REF,
    ZVFS_OP_ADD_REF_BATCH,
    ZVFS_OP_RESET_BLOBSTORE
};

inline const char* cast_opcode2string(uint32_t op){
    switch (op)
    {
    case ZVFS_OP_CREATE:
        return "CREATE";
        break;
    case ZVFS_OP_OPEN:
        return "OPEN";
        break;
    case ZVFS_OP_READ:
        return "READ";
        break;
    case ZVFS_OP_WRITE:
        return "WRITE";
        break;
    case ZVFS_OP_RESIZE:
        return "RESIZE";
        break;
    case ZVFS_OP_SYNC_MD:
        return "SYNC";
        break;
    case ZVFS_OP_CLOSE:
        return "CLOSE";
        break;
    case ZVFS_OP_DELETE:
        return "DELETE";
        break;
    case ZVFS_OP_ADD_REF:
        return "ADD_REF";
        break;
    case ZVFS_OP_ADD_REF_BATCH:
        return "ADD_REF_BATCH";
        break;
    case ZVFS_OP_RESET_BLOBSTORE:
        return "RESET_BLOBSTORE";
        break;
    default:
        break;
    }
    return "ERROR";
}

#define ZVFS_WRITE_F_AUTO_GROW (1u << 0)

/* 最小固定头（同步阻塞场景，不含 request_id） */
struct zvfs_req_header {
    uint32_t opcode;
    uint32_t payload_len;
};

struct zvfs_resp_header {
    uint32_t opcode;
    int32_t status;
    uint32_t payload_len;
};

/* -------------------- per-op request body -------------------- */

struct zvfs_req_create_body {
    uint64_t size_hint;
};

struct zvfs_req_open_body {
    uint64_t blob_id;
};

struct zvfs_req_read_body {
    uint64_t handle_id;
    uint64_t offset;
    uint64_t length;
};

struct zvfs_req_write_body {
    uint64_t handle_id;
    uint64_t offset;
    uint64_t length;
    uint32_t flags;
    const void *data;
};

struct zvfs_req_resize_body {
    uint64_t handle_id;
    uint64_t new_size;
};

struct zvfs_req_sync_md_body {
    uint64_t handle_id;
};

struct zvfs_req_close_body {
    uint64_t handle_id;
};

struct zvfs_req_delete_body {
    uint64_t blob_id;
};

struct zvfs_add_ref_item {
    uint64_t handle_id;
    uint32_t ref_delta;
};

struct zvfs_req_add_ref_body {
    uint64_t handle_id;
    uint32_t ref_delta;
};

struct zvfs_req_add_ref_batch_body {
    uint32_t item_count;
    const struct zvfs_add_ref_item *items;
};

/* -------------------- per-op response body -------------------- */

struct zvfs_resp_create_body {
    uint64_t blob_id;
    uint64_t handle_id;
};

struct zvfs_resp_open_body {
    uint64_t handle_id;
    uint64_t size;
};

struct zvfs_resp_read_body {
    uint64_t length;
    void *data;
};

struct zvfs_resp_write_body {
    uint64_t bytes_written;
};

/* resize/sync_md/close/delete 成功时 body 为空 */
size_t zvfs_serialize_resp_resize(uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_resp_resize(const uint8_t *buf, size_t buf_len);
size_t zvfs_serialize_resp_sync_md(uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_resp_sync_md(const uint8_t *buf, size_t buf_len);
size_t zvfs_serialize_resp_close(uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_resp_close(const uint8_t *buf, size_t buf_len);
size_t zvfs_serialize_resp_delete(uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_resp_delete(const uint8_t *buf, size_t buf_len);

/* -------------------- 兼容旧接口 req/resp -------------------- */

struct zvfs_req {
    uint32_t opcode;

    uint64_t size_hint;
    uint64_t blob_id;
    uint64_t handle_id;

    uint64_t offset;
    uint64_t length;
    uint32_t write_flags;
    void *data;

    uint32_t ref_delta;
    uint32_t add_ref_count;
    struct zvfs_add_ref_item *add_ref_items;

    struct zvfs_conn *conn;
    struct zvfs_blob_handle *handle;
};

struct zvfs_resp {
    uint32_t opcode;
    int32_t status;

    uint64_t blob_id;
    uint64_t handle_id;
    uint64_t size;

    uint64_t length;
    void *data;

    uint64_t bytes_written;

    struct zvfs_conn *conn;
};

/* -------------------- 头部序列化/反序列化 -------------------- */

size_t zvfs_serialize_req_header(const struct zvfs_req_header *header, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_req_header(const uint8_t *buf, size_t buf_len, struct zvfs_req_header *header);

size_t zvfs_serialize_resp_header(const struct zvfs_resp_header *header, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_resp_header(const uint8_t *buf, size_t buf_len, struct zvfs_resp_header *header);

/* -------------------- request body 序列化/反序列化 -------------------- */

size_t zvfs_serialize_req_create(const struct zvfs_req_create_body *body, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_req_create(const uint8_t *buf, size_t buf_len, struct zvfs_req_create_body *body);

size_t zvfs_serialize_req_open(const struct zvfs_req_open_body *body, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_req_open(const uint8_t *buf, size_t buf_len, struct zvfs_req_open_body *body);

size_t zvfs_serialize_req_read(const struct zvfs_req_read_body *body, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_req_read(const uint8_t *buf, size_t buf_len, struct zvfs_req_read_body *body);

size_t zvfs_serialize_req_write(const struct zvfs_req_write_body *body, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_req_write(const uint8_t *buf, size_t buf_len, struct zvfs_req_write_body *body);

size_t zvfs_serialize_req_resize(const struct zvfs_req_resize_body *body, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_req_resize(const uint8_t *buf, size_t buf_len, struct zvfs_req_resize_body *body);

size_t zvfs_serialize_req_sync_md(const struct zvfs_req_sync_md_body *body, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_req_sync_md(const uint8_t *buf, size_t buf_len, struct zvfs_req_sync_md_body *body);

size_t zvfs_serialize_req_close(const struct zvfs_req_close_body *body, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_req_close(const uint8_t *buf, size_t buf_len, struct zvfs_req_close_body *body);

size_t zvfs_serialize_req_delete(const struct zvfs_req_delete_body *body, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_req_delete(const uint8_t *buf, size_t buf_len, struct zvfs_req_delete_body *body);

size_t zvfs_serialize_req_add_ref(const struct zvfs_req_add_ref_body *body, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_req_add_ref(const uint8_t *buf, size_t buf_len, struct zvfs_req_add_ref_body *body);

size_t zvfs_serialize_req_add_ref_batch(const struct zvfs_req_add_ref_batch_body *body, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_req_add_ref_batch(const uint8_t *buf, size_t buf_len, struct zvfs_req_add_ref_batch_body *body);

/* -------------------- response body 序列化/反序列化 -------------------- */

size_t zvfs_serialize_resp_create(const struct zvfs_resp_create_body *body, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_resp_create(const uint8_t *buf, size_t buf_len, struct zvfs_resp_create_body *body);

size_t zvfs_serialize_resp_open(const struct zvfs_resp_open_body *body, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_resp_open(const uint8_t *buf, size_t buf_len, struct zvfs_resp_open_body *body);

size_t zvfs_serialize_resp_read(const struct zvfs_resp_read_body *body, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_resp_read(const uint8_t *buf, size_t buf_len, struct zvfs_resp_read_body *body);

size_t zvfs_serialize_resp_write(const struct zvfs_resp_write_body *body, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_resp_write(const uint8_t *buf, size_t buf_len, struct zvfs_resp_write_body *body);

/* -------------------- 兼容封装 -------------------- */

size_t zvfs_serialize_req(struct zvfs_req *req, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_req(uint8_t *buf, size_t buf_len, struct zvfs_req *req);

size_t zvfs_serialize_resp(struct zvfs_resp *resp, uint8_t *buf, size_t buf_len);
size_t zvfs_deserialize_resp(uint8_t *buf, size_t buf_len, struct zvfs_resp *resp);

#ifdef __cplusplus
}
#endif

#endif
