/*
 * @Description: 
 * @Version: 1.0
 * @Autor: lishengyin
 * @Date: 2021-11-03 15:16:14
 * @LastEditors: lishengyin
 * @LastEditTime: 2022-06-22 11:35:11
 */
#pragma once

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

#include "Util/logger.h"
#include "Util/NoticeCenter.h"
#include "Poller/EventPoller.h"
#include "Util/SqlPool.h"
#include "Network/TcpClient.h"
#include "Poller/Timer.h"

using namespace std;

template <class T1, class T2>
class HttpResultMsg
{
public:
    std::string code;
    std::string status;

    std::string msg;
    vector<T1> datas;
    vector<T2> extendDatas;

    std::string attr1;
    std::string attr2;
    std::string attr3;

    bool notOk;
    bool ok;

public:
    HttpResultMsg(){}
    ~HttpResultMsg(){}

    /**
     * @description: json转码为对象
     * @param {const std::string& json} json数据
     * @return {*}
     */    
    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();
        if (end == doc.FindMember("code") || !doc["code"].IsString()) {
            return false;
        } else {
            code = doc["code"].GetString();
        }
        if (end == doc.FindMember("notOk") || !doc["notOk"].IsBool()) {
            return false;
        } else {
            notOk = doc["notOk"].GetBool();
        }
        if (end == doc.FindMember("ok") || !doc["ok"].IsBool()) {
            return false;
        } else {
            ok = doc["ok"].GetBool();
        }
        
        if (end != doc.FindMember("data")) {
            if(doc["data"].IsObject()){
                T1 data;
                const rapidjson::Value& object = doc["data"];
                if(!(data.jsonToObject(object))){
                    return false;
                }
                datas.push_back(data);
            }else if(doc["data"].IsArray()){
                const rapidjson::Value& objs = doc["data"];
                for (size_t i = 0; i < objs.Size(); i++) {
                    const rapidjson::Value& obj = objs[i];
                    T1 data;
                    if(!(data.jsonToObject(obj))){
                        return false;
                    }
                    datas.push_back(data);
                }
            }
        }
        
        if (end != doc.FindMember("extendData")) {
            if(doc["extendData"].IsObject()){
                T2 extendData;
                const rapidjson::Value& object = doc["extendData"];
                if(!(extendData.jsonToObject(object))){
                    return false;
                }
                extendDatas.push_back(extendData);
            }else if(doc["extendData"].IsArray()){
                const rapidjson::Value& objs = doc["extendData"];
                for (size_t i = 0; i < objs.Size(); ++i) {
                    const rapidjson::Value& obj = objs[i];
                    T2 extendData;
                    if(!(extendData.jsonToObject(obj))){
                        return false;
                    }
                    extendDatas.push_back(extendData);
                }
            }
        }
        return true;
    }

    /**
     * @description: objectToJson
     * @param {string&} str
     * @return {*}
     */    
    void objectToJson(std::string& str)
    {
        rapidjson::StringBuffer strBuf;
        rapidjson::Writer<rapidjson::StringBuffer> writer(strBuf);
        writer.StartObject();

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

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

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

        writer.Key("datas");

        writer.StartArray();
        for(auto iter = datas.begin(); iter != datas.end(); iter++){
            iter->ObjectToJson(writer);
        }
        writer.EndArray();

        writer.Key("extendDatas");
        writer.StartArray();
        for(auto iter = extendDatas.begin(); iter != extendDatas.end(); iter++){
            iter->ObjectToJson(writer);
        }
        writer.EndArray();
    
        writer.Key("attr1");
        writer.String(attr1.c_str());

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

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

        writer.Key("notOk");
        writer.Bool(notOk);

        writer.Key("ok");
        writer.Bool(ok);



        writer.EndObject();
        str = strBuf.GetString();
    }

};