/*
 * @Description: 
 * @Version: 1.0
 * @Autor: lishengyin
 * @Date: 2022-02-23 09:32:08
 * @LastEditors: lishengyin
 * @LastEditTime: 2022-07-07 08:48:08
 */
#include "HttpClient.h"

namespace gsd{
    std::shared_ptr<httplib::Client> m_httpClient = nullptr;

    /**
    * @description: 创建对象
    * @param {*}
    * @return {*}
    */    
    std::shared_ptr<HttpClient> HttpClient::CreateNew(){
        static shared_ptr<HttpClient> httpClient = nullptr;
        if(httpClient == nullptr) httpClient = std::make_shared<HttpClient>();
        return httpClient;
    }

    /**
    * @description: 初始化
    * @param {*}
    * @return {*}
    */    
    int32_t HttpClient::Init(std::string account,std::string url, int port){
        this->account = account;
        m_httpClient = std::make_shared<httplib::Client>(url, port);
        if(m_httpClient == NULL){
            ErrorL << "HttpClient initialization failed";
            return ERR;
        }
        if(this->LoginNetty() != OK){
            ErrorL << "Failed to log in to netty";
            return ERR;
        }
        return OK;
    }

    /**
    * @description: 登录Netty获取token
    * @param {*}
    * @return {*}
    */
    int32_t HttpClient::LoginNetty(){
        if(m_httpClient == nullptr) return ERR;
        // 获取时间
        char ctime[80];
        getDataTime(ctime);
        string reqTime = ctime;
        std::string reqSign = md5(this->privateKey + this->account + this->pwd + reqTime);

        httplib::Params params;
        params.emplace("account", this->account);
        params.emplace("reqSign", reqSign);
        params.emplace("reqTime", reqTime);

        if (auto res = m_httpClient->Post("/BMP-WEB/user/pass/loginByNetty",params)){
            if (res->status == 200) {
                NettyHttpResultMsg<NettyHttpNull,NettyHttpToken> nettyHttpResultMsg;
                // 解析数据
                if(!nettyHttpResultMsg.jsonToObject(res->body)){
                    return ERR;
                }
                // 获取token
                if(nettyHttpResultMsg.extendDatas.size()){
                    this->authToken = nettyHttpResultMsg.extendDatas[0].authToken;
                    this->refreshToken = nettyHttpResultMsg.extendDatas[0].refreshToken;
                    return OK;
                }
                return ERR;
            }
            return ERR;
        }else{
            auto err = res.error();
            ErrorL << "The service is not available," << err << endl;
            return ERR;
        }
        return OK;
    }

    /**
    * @description: 获取时间
    * @param {char} *ctime
    * @return {*}
    */    
    void HttpClient::getDataTime(char *ctime)
    {
        time_t rawtime;
        struct tm *info;
        time(&rawtime);
        info = localtime(&rawtime);
        strftime(ctime, 80, "%Y-%m-%d %H:%M:%S", info);
    }

    /**
    * @description: 判断是否获取到Token
    * @param {*}
    * @return {*}
    */    
    bool HttpClient::alive(){
        return this->authToken  == "" ? false : true;
    }

    /**
    * @description: 获取驱鸟设备信息
    * @param {*}
    * @return {*}
    */    
    int32_t HttpClient::getExpelInfo(std::string simCode, NettyHttpResultMsg<NettyExpelDevInfo,NettyHttpNull>& nettyHttpResultMsg){
        if(m_httpClient == nullptr) return ERR;
        httplib::Headers headers = {
            { "authToken", this->authToken},
            { "authUid", this->account},
        };
        httplib::Params params;
        params.emplace("simCode", simCode);
        if (auto res = m_httpClient->Post("/BMP-WEB/device/findBySimCode",headers, params)){
            if (res->status == 200) {
                if(nettyHttpResultMsg.jsonToObject(res->body)){
                    return OK;
                }
                return ERR;
            }
            return ERR;
        }else{
            auto err = res.error();
            ErrorL << "The service is not available," << err << endl;
            return ERR;
        }
        return OK;
    }

    /**
    * @description: 获取数字字典
    * @param {*}
    * @return {*}
    */
    int32_t HttpClient::getHttpDicCode(std::string dictCode,NettyHttpResultMsg<NettyHttpDicCode,NettyHttpNull>& nettyHttpResultMsg){
        if(m_httpClient == nullptr) return ERR;
        httplib::Headers headers = {
            { "authToken", this->authToken},
            { "authUid", this->account},
        };

        httplib::Params params;
        params.emplace("appId", "1");
        params.emplace("dictCode", dictCode);
        params.emplace("dictType", "2");
        
        if (auto res = m_httpClient->Post("/BMP-WEB/dict/selectByDictCodeAndDictType",headers, params)){
            if (res->status == 200) {
                if(nettyHttpResultMsg.jsonToObject(res->body)){
                    return OK;
                }
            }
            ErrorL << res->body << endl;
            return ERR;
        }else{
            auto err = res.error();
            ErrorL << "The service is not available," << err << endl;
            return ERR;
        }
        return OK;
    }
};
