#ifndef __RESP_H__
#define __RESP_H__

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

#define RESP_MAX_ARGC  16
#define RESP_MAX_LINE  1024
#define RESP_MAX_BULK  (16u * 1024u * 1024u) /* 16MB default */

/**
 * SET 
 */

typedef enum {
	KVS_CMD_START = 0,
	// array
	KVS_CMD_SET = KVS_CMD_START,
	KVS_CMD_GET,
	KVS_CMD_DEL,
	KVS_CMD_MOD,
	KVS_CMD_EXIST,
	// rbtree
	KVS_CMD_RSET,
	KVS_CMD_RGET,
	KVS_CMD_RDEL,
	KVS_CMD_RMOD,
	KVS_CMD_REXIST,
	// hash
	KVS_CMD_HSET,
	KVS_CMD_HGET,
	KVS_CMD_HDEL,
	KVS_CMD_HMOD,
	KVS_CMD_HEXIST,
	
	KVS_CMD_SAVE,
	KVS_CMD_PSYNC,
	KVS_CMD_COUNT,
}kvs_cmd_t;

typedef struct resp_slice_s {
    const uint8_t *ptr;
    uint32_t len;
} resp_slice_t;

typedef struct resp_cmd_s {
    uint32_t argc;
    resp_slice_t argv[RESP_MAX_ARGC]; /* argv[0] is command name */
} resp_cmd_t;

typedef enum resp_type_e {
    RESP_T_SIMPLE_STR,
    RESP_T_ERROR,
    RESP_T_INTEGER,
    RESP_T_BULK_STR,
    RESP_T_NIL,          /* nil bulk string ($-1\r\n) */
} resp_type_t;

typedef struct resp_value_s {
    resp_type_t type;
    int64_t i64;         /* for integer */
    resp_slice_t bulk;   /* for simple/error/bulk string (bytes) */
} resp_value_t;

/* ----------------- parsing ----------------- */
/* Parse one RESP command from [buf, buf+len).
 * return: -1 protocol error, 0 need more data, >0 bytes consumed
 */
int resp_parse_one_cmd(const uint8_t *buf, int len, resp_cmd_t *out_cmd);

/* ----------------- response building ----------------- */
/* Build RESP value into out buffer. return bytes written, -1 on error/capacity. */
int resp_build_value(const resp_value_t *v, uint8_t *out, size_t cap);

/* Convenience helpers */
resp_value_t resp_simple(const char *s); /* +s\r\n */
resp_value_t resp_error(const char *s);  /* -s\r\n */
resp_value_t resp_int(int64_t x);        /* :x\r\n */
resp_value_t resp_bulk(const uint8_t *p, uint32_t n); /* $n\r\n...\r\n */
resp_value_t resp_nil(void);             /* $-1\r\n */

/* ----------------- dispatcher ----------------- */
/* Execute one command and return a RESP value.
 * NOTE: output value may reference storage memory (for GET), so build response
 * promptly after this call.
 */
int resp_dispatch(const resp_cmd_t *cmd, resp_value_t *out_value);

#endif