
#include "test_client.h"
#include <stdio.h>
#include <errno.h>
#include <unistd.h>

int kvs_need(const uint8_t *p, const uint8_t *end, size_t n) {
	return (p + n <= end) ? 0 : -1;
}

// 注意u8类型不需要ntoh或者hton
int kvs_read_u8(const uint8_t **pp, const uint8_t *end, uint8_t *out) {
	const uint8_t *p = *pp;
	if (kvs_need(p, end, 1) < 0) return -1;
	*out = *p;
	*pp = p + 1;
	return 0;
}

int kvs_read_u16(const uint8_t **pp, const uint8_t *end, uint16_t *out) {
	const uint8_t *p = *pp;
	if (kvs_need(p, end, 2) < 0) return -1;
	uint16_t v;
	memcpy(&v, p, 2);
	*out = ntohs(v);
	*pp = p + 2;
	return 0;
}

int kvs_read_u32(const uint8_t **pp, const uint8_t *end, uint32_t *out) {
	const uint8_t *p = *pp;
	if (kvs_need(p, end, 4) < 0) return -1;
	uint32_t v;
	memcpy(&v, p, 4);
	*out = ntohl(v);
	*pp = p + 4;
	return 0;
}

int kvs_write_u8(uint8_t **pp, const uint8_t *end, uint8_t v) {
	uint8_t *p = *pp;
	if (kvs_need(p, end, 1) < 0) return -1;
	*p = v;
	*pp = p + 1;
	return 0;
}

int kvs_write_u16(uint8_t **pp, const uint8_t *end, uint16_t v) {
	uint8_t *p = *pp;
	if (kvs_need(p, end, 2) < 0) return -1;
	uint16_t be = htons(v);
	memcpy(p, &be, 2);
	*pp = p + 2;
	return 0;
}

int kvs_write_u32(uint8_t **pp, const uint8_t *end, uint32_t v) {
	uint8_t *p = *pp;
	if (kvs_need(p, end, 4) < 0) return -1;
	uint32_t be = htonl(v);
	memcpy(p, &be, 4);
	*pp = p + 4;
	return 0;
}



int getcmd(uint8_t op, const char *key, uint32_t key_len, const char *value, uint32_t value_len, uint8_t *buf){
	if(!buf) return -1;
	uint8_t *end = buf + CMD_SIZE;
	uint8_t *p = buf;
	uint8_t argc = (key == NULL)?0:1;
	argc += (value == NULL)?0:1;


	if (kvs_write_u8(&p, end, op) < 0) return -1;
	if (kvs_write_u8(&p, end, argc) < 0) return -1;
	

	// 写入 key
	if(key){
		int keylen = key_len;
		if (kvs_write_u32(&p, end, keylen) < 0) return -1;
		if (kvs_need(p, end, keylen) < 0) return -1;
		if (keylen > 0) {
			memcpy(p, key, keylen);
			p += keylen;
		}
	}

	if(value){
		int vallen = value_len;
		if (kvs_write_u32(&p, end, vallen) < 0) return -1;
		if (kvs_need(p, end, vallen) < 0) return -1;
		if (vallen > 0) {
			memcpy(p, value, vallen);
			p += vallen;
		}
	}

	return (p - buf);
}

int parse_response(const uint8_t *buf, int buflen, kvs_response_t *rsp) {
	if(buflen == 0) return 0;
	const uint8_t *p = buf;
	const uint8_t *end = buf + buflen;
	
	// 读取 OP
	if (kvs_read_u8(&p, end, &rsp->op) < 0) {
		fprintf(stderr, "Failed to read op\n");
		return -1;
	}
	
	// 读取 status
	if (kvs_read_u8(&p, end, &rsp->status) < 0) {
		fprintf(stderr, "Failed to read status\n");
		return -1;
	}
	
	// 读取 datalen
	if (kvs_read_u32(&p, end, &rsp->datalen) < 0) {
		fprintf(stderr, "Failed to read datalen\n");
		return -1;
	}
	
	// 检查数据长度
	if (kvs_need(p, end, rsp->datalen) < 0) {
		fprintf(stderr, "Data length mismatch: expected %u bytes, but only %ld available\n", 
				rsp->datalen, end - p);
		return -1;
	}
	
	// 指向数据部分
	rsp->data = (uint8_t *)p;
	
	return (p - buf) + rsp->datalen;
}


void print_response(const char *cmd_name, const kvs_response_t *rsp) {
	printf("%s ", cmd_name);
	if(rsp->op == KVS_CMD_GET || rsp->op == KVS_CMD_HGET || rsp->op == KVS_CMD_RGET){
		if (rsp->datalen > 0 && rsp->data != NULL) {
			printf("Data: ");
			// 尝试以字符串形式打印（如果是可打印字符）
			int is_printable = 1;
			for (uint32_t i = 0; i < rsp->datalen; i++) {
				if (rsp->data[i] < 32 || rsp->data[i] > 126) {
					is_printable = 0;
					break;
				}
			}
			
			if (is_printable) {
				printf("\"");
				for (uint32_t i = 0; i < rsp->datalen; i++) {
					printf("%c", rsp->data[i]);
				}
				printf("\"\n");
			} else {
				// 以十六进制打印
				printf("0x");
				for (uint32_t i = 0; i < rsp->datalen; i++) {
					printf("%02x", rsp->data[i]);
				}
				printf("\n");
			}
		} else {
			printf("Data: (empty)\n");
		}
	}else {
		switch (rsp->status) {
			case KVS_STATUS_OK:
				printf("(OK)\n");
				break;
			case KVS_STATUS_ERROR:
				printf("(ERROR)\n");
				break;
			case KVS_STATUS_NO_EXIST:
				printf("(NO_EXIST)\n");
				break;
			case KVS_STATUS_EXIST:
				printf("(EXISTS)\n");
				break;
			default:
				printf("(UNKNOWN)\n");
				break;
		}
	}
}

int verify_response(const kvs_response_t *rsp, uint8_t expected_op, 
                    uint8_t expected_status, const char *expected_data, uint32_t expected_len) {
	if (rsp->op != expected_op) {
		printf("❌ OP mismatch: expected %u, got %u\n", expected_op, rsp->op);
		return 0;
	}
	
	if (rsp->status != expected_status) {
		printf("❌ Status mismatch: expected %u, got %u\n", expected_status, rsp->status);
		return 0;
	}
	
	if (expected_data != NULL) {
		if (rsp->datalen != expected_len) {
			printf("❌ Data length mismatch: expected %u, got %u\n", expected_len, rsp->datalen);
			return 0;
		}
		
		if (memcmp(rsp->data, expected_data, expected_len) != 0) {
			printf("❌ Data content mismatch\n");
			return 0;
		}
	}
	
	return 1;
}


