#pragma once


#include <iostream>
#include <rapidjson/document.h>
#include <rapidjson/rapidjson.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>

using namespace std;

template <typename T>
class NettyClientResultMsg
{
private:
    // 对应客户端该次请求id，客户端生成，需保证唯一，方便请求与响应对应
	std::string requestId;
	// 客户端传输到服务端的数据类型
	std::string dataType;
    // 客户端传输到服务端的数据内容
    T data;

public:
    NettyClientResultMsg(/* args */){}
    ~NettyClientResultMsg(){}
    std::string getRequestId(){
        return requestId;
    }
    std::string getDataType(){
        return dataType;
    }
    T getData(){
        return data;
    }
    void setRequestId(std::string RequestId){
        requestId = RequestId;
    }
    void setDataType(std::string DataType){
        dataType = DataType;
    }
    void setData(T Data){
        data = Data;
    }
    void objectToJson(std::string& str)
    {
        rapidjson::StringBuffer strBuf;
        rapidjson::Writer<rapidjson::StringBuffer> writer(strBuf);
        writer.StartObject();

        writer.Key("requestId");
        writer.String(requestId.c_str());

        writer.Key("dataType");
        writer.String(dataType.c_str());

        writer.Key("data");
        data.objectToJson(writer);

        writer.EndObject();
        str = strBuf.GetString();
    }
    bool jsonToObject(const std::string& json)
    {
        rapidjson::Document doc;
        if (doc.Parse<rapidjson::kParseCommentsFlag>(json.c_str()).HasParseError()) {
            return false;
        }
        // get members
        const auto end = doc.MemberEnd();

        // json_type
        if (end == doc.FindMember("requestId") || !doc["requestId"].IsString()) {
            return false;
        } else {
            requestId = doc["requestId"].GetString();
        }

        if (end == doc.FindMember("dataType") || !doc["dataType"].IsString()) {
            return false;
        } else {
            dataType = doc["dataType"].GetString();
        }

        if (end == doc.FindMember("data") || !doc["data"].IsObject()) {
            return false;
        } else {
            std::string strJson = doc["data"].GetString();
            if(!data.jsonToObjet(strJson)){
                return false;
            };
        }
        return true;
    }
};
