#ifndef __KVS_RW_TOOLS_H__
#define __KVS_RW_TOOLS_H__

#include <stdint.h>
#include <stdio.h>
int kvs_need(const uint8_t *p, const uint8_t *end, size_t n);
int kvs_read_u8(const uint8_t **pp, const uint8_t *end, uint8_t *out);
int kvs_read_u16(const uint8_t **pp, const uint8_t *end, uint16_t *out);
int kvs_read_u32(const uint8_t **pp, const uint8_t *end, uint32_t *out);

int kvs_write_u8(uint8_t **pp, const uint8_t *end, uint8_t v);
int kvs_write_u16(uint8_t **pp, const uint8_t *end, uint16_t v);
int kvs_write_u32(uint8_t **pp, const uint8_t *end, uint32_t v);



/**
 * Header: 	| magic(4) | type(1) | payloadLen(4) | reqId(4) | flag1(1) | flag2(2) |
 * 
 * Request
 * Payload: | opcount(4) | repeat Cmd | 
 * Cmd: 	| OP(1) | argc(4) | repeat Arg |
 * Arg:		| arglen(4) | arg |
 * 
 * Response
 * Payload: | opcount(4) | repeat Cmd | 
 * Cmd:		| status(1) | datalen(4) | data | 
 */

#define KVS_HDR_LEN 16  // | magic(4) | type(1) | payloadLen(4) | reqId(4) | flag1(1) | flag2(2) |
#define KVS_MAGIC 0x4B565331u 
#define KVS_TYPE_REQ  1
#define KVS_TYPE_RESP 2

#define KVS_MAX_OPCOUNT 1024
#define KVS_MAX_RESPONSE (64 * 1024)

enum {
	KVS_STATUS_OK = 0,
	KVS_STATUS_ERROR = 1,
	KVS_STATUS_NO_EXIST = 2,
	KVS_STATUS_EXIST = 3,
	KVS_STATUS_BADREQ = 4
};


typedef struct {
	uint8_t  op;       
	uint32_t argc;     
	char   **argv;     
} kvs_op_t;

typedef struct {
	uint32_t magic;
	uint8_t  type;
	uint32_t payloadLen;
	uint32_t reqId;
	uint8_t  flag1;
	uint16_t flag2;

	// payload ops
	uint32_t opcount;
	kvs_op_t *ops;

	// consumed bytes (header+payload)
	uint32_t consumed;
} kvs_request_t;

typedef struct {
	uint8_t status;
	uint32_t datalen;
	const char *data_ptr;
} kvs_response_t;

int kvs_parse_request(const uint8_t *msg, int length, kvs_request_t *req_out);
int kvs_execute_request(const kvs_request_t *req, kvs_response_t *results);
int kvs_build_response(const kvs_request_t *req,
                              const kvs_response_t *results,
                              uint8_t *response, int response_cap);
void kvs_free_request(kvs_request_t *req);
void kvs_exec_one_op(uint8_t op, uint32_t argc, char **argv,
                        uint8_t *status_out,
                        const char **data_out, uint32_t *dlen_out);

#endif
