#define DM_HEADER_SIZE 64 // 64

#define DM_PAYLOAD_OFFSET DM_HEADER_SIZE
//#define DM_SVR_ENCODING_OFFSET 28

//#define DM_VERSION_CLI 0xc8
//#define DM_DO_LOGIN  0x01

//#define DM_STMT_BEGIN 0x03 //bb
#define DM_QUERY 0x05 //bb
//#define DM_STMT_PREPARE DM_QUERY //00
#define DM_STMT_EXECUTE 0x0d //bb
//#define DM_STMT_CLOSE 0x04  // 00

#define DM_RESPONSE_OK    0xbb
#define DM_RESPONSE_EOF   0x00

//#define DM_RESPONSE_ERROR 0xa0 、0x9d ...
//10-13 4位 响应码 小于0的为错误
//跳过'-7036'这个错误码， 参考go-dm: EC_RN_EXCEED_ROWSET_SIZE = newDmError(-7036, "")
#define DM_SVR_ERR_CODE_EC_RN_EXCEED_ROWSET_SIZE -7036

/*
 * DM packet:
 *          |                  |0        3|4     5|6     9|
 *          |        TCP       |  Herder  | type  |  len  |
 * 0x0020:  5018 01f5 6210 0000 0100 0000  0500    5000    P...b.........P.
 *
*/

static __always_inline
int is_dm_query(char *buf, __u64 buf_size, __u8 *request_type) {
//    bpf_printk("===== DM-req Begin ...");

//    bpf_printk("===== DM-req buf_size :%d",buf_size);
    //是否满足header大小
    if (buf_size < DM_HEADER_SIZE) {
        return 0;
    }

    //读取10个字节
    __u8 b[10];
    bpf_read(buf, b);

//	bpf_printk("buf0:[0x%x]",b[0]);
//	bpf_printk("buf1:[0x%x]",b[1]);
//	bpf_printk("buf2:[0x%x]",b[2]);
//	bpf_printk("buf3:[0x%x]",b[3]);
//
//	bpf_printk("buf4:[0x%x]",b[4]);
//	bpf_printk("buf5:[0x%x]",b[5]);
//
//	bpf_printk("buf6:[0x%x]",b[6]);
//	bpf_printk("buf7:[0x%x]",b[7]);
//	bpf_printk("buf8:[0x%x]",b[8]);
//	bpf_printk("buf9:[0x%x]",b[9]);

    __s32 body_size = (__s32)(b[6]& 0xff) | ((__s32)b[7]&0xff) << 8 | ((__s32)b[8]&0xff) << 16 | ((__s32)b[9]&0xff) << 24 ;
//    bpf_printk("===== DM-req body_size [%d] ", body_size);

    if( DM_HEADER_SIZE + body_size < buf_size ) {
        return 0;
     }

//     if(body_size > 0) {
//      __u8 bb[4];
//      bpf_read(buf+DM_PAYLOAD_OFFSET, bb);
//
//      __s32 tmp_len = (__s32)(bb[0]& 0xff) | ((__s32)bb[1]&0xff) << 8 | ((__s32)bb[2]&0xff) << 16 | ((__s32)bb[3]&0xff) << 24 ;
//      if(tmp_len>0){
//        char* bbb[10];
//        bpf_read(buf+68, bbb);
//        bpf_printk("===== DM-req payload:%s",bbb);
//      }
//     }


   __s16 pack_type =  (__s16)(b[4]& 0xff) | ((__s16)b[5]&0xff) << 8 ;
//    bpf_printk("===== DM-req pack_type <0x%x> [%d] ", pack_type,pack_type);
    if (pack_type == DM_QUERY || pack_type == DM_STMT_EXECUTE) {
            *request_type = pack_type;
            return 1;
    }

//    bpf_printk("===== DM-req end not dm-req ...\n");
    return 0;
}


static __always_inline
int is_dm_response(char *buf, __u64 buf_size, __u8 request_type, __u32 *status) {

//    bpf_printk("===== DM-resp  Begin ...");

//	bpf_printk("===== DM-resp buf_size :%d",buf_size);
     if (buf_size < DM_HEADER_SIZE) {
           return 0;
     }
	__u8 b[14];
    bpf_read(buf, b);

//	bpf_printk("buf0:[0x%x]",b[0]);
//	bpf_printk("buf1:[0x%x]",b[1]);
//	bpf_printk("buf2:[0x%x]",b[2]);
//	bpf_printk("buf3:[0x%x]",b[3]);
//
//	bpf_printk("buf4:[0x%x]",b[4]);
//	bpf_printk("buf5:[0x%x]",b[5]);
//
//	bpf_printk("buf6:[0x%x]",b[6]);
//	bpf_printk("buf7:[0x%x]",b[7]);
//	bpf_printk("buf8:[0x%x]",b[8]);
//	bpf_printk("buf9:[0x%x]",b[9]);
//
//    bpf_printk("buf10:[0x%x]",b[10]);
//    bpf_printk("buf11:[0x%x]",b[11]);
//    bpf_printk("buf12:[0x%x]",b[12]);
//    bpf_printk("buf13:[0x%x]",b[13]);

  __s32 body_size = (__s32)(b[6]& 0xff) | ((__s32)b[7]&0xff) << 8 | ((__s32)b[8]&0xff) << 16 | ((__s32)b[9]&0xff) << 24 ;
//	bpf_printk("===== DM-resp body_size [%d] ", body_size);

	//0xbb响应时要考虑数据分段传输的情况(DM_HEADER_SIZE + body_size > buf_size)
	if( DM_HEADER_SIZE + body_size  < buf_size ) {
            return 0;
    }

    __s16 pack_type =  (__s16)(b[4]& 0xff) | ((__s16)b[5]&0xff) << 8 ;
//    bpf_printk("===== DM-resp pack_type <0x%x> [%d] ", pack_type,pack_type);
//    bpf_printk("===== DM-resp request_type <0x%x> [%d] ", request_type,request_type);


    if (pack_type == DM_RESPONSE_OK) {
        //收到响应后查询请求流程结束
        if(request_type == DM_QUERY || request_type == DM_STMT_EXECUTE ) {
           *status = STATUS_OK;
           return 1;
        }
        return 0;
    }

    //判断是否报错 10-13 4位 响应码 小于0的 为错误
    __s32 svr_msg_code= (__s32)(b[10]& 0xff) | ((__s32)b[11]&0xff) << 8 | ((__s32)b[12]&0xff) << 16 | ((__s32)b[13]&0xff) << 24 ;
    if( svr_msg_code < 0 &&  svr_msg_code != DM_SVR_ERR_CODE_EC_RN_EXCEED_ROWSET_SIZE ){
       //检测到错误后，请求流程结束
//       bpf_printk("===== DM-resp svr_msg_code request_type <0x%x>, svr_msg_code [%d]",request_type,svr_msg_code);
       *status = STATUS_FAILED;
       return 1;
     }

//    bpf_printk("===== DM-resp End  not dm-resp...");
    return 0;
}
