//
// Created by Mr.V on 2024/4/3.
//

#include "UpResultThread.h"


UpResultThread::UpResultThread(MQueue<TrainInfo> *queueTrainInfo, QObject *parent) :
    QThread(parent)
{
    this->queueTrainInfo_ = queueTrainInfo;

    // 配置文件读取
    QString errorMessage = "";
    if (!ConfigUtil::readBaseConfig(g_config_path, errorMessage, this->baseConfig_))
    {
        this->ErrorSignals(errorMessage);
    }
    if (!ConfigUtil::readInterfaceConfig(g_config_path, errorMessage, this->interfaceConfig_))
    {
        this->ErrorSignals(errorMessage);
    }
}

void UpResultThread::run()
{
    while (true)
    {
//        if ((*this->iDirection == 0 && this->queueTrainInfo_->size() <= 4) || *this->iDirection < 0) continue;

        while (!this->queueTrainInfo_->isEmpty())
        {
            TrainInfo trainInfo_ = this->queueTrainInfo_->pop();
            if (!this->upWeb(trainInfo_))
            {
                //this->logError("第" + QString::fromStdString(trainInfo.strOrder) + "节，识别结果上传失败！");
            }
        }
        QThread::sleep(1);
    }
}

/**
 * @brief:Http发送RFID数据
 * @param：carriageType：车型
 * @param：carriageNumber：车号
 * @param：carriageOrder：车节号
 * @param：time：当前时间
 * @param：rfidSourceInfo：RFID的原始数据（过滤掉了重复磁条信息）
 * @return: 成功:true
 *          失败:false
 */
bool UpResultThread::upWeb(TrainInfo &trainInfo)
{
    try {
        Json::Value arrayObj;		//构建对象

        arrayObj["comeTime"] = trainInfo.trainTime;
        arrayObj["collectTime"] = trainInfo.collectTime;
        arrayObj["carriageNumber"] = trainInfo.carriageNum;
        arrayObj["carriageType"] = trainInfo.carriageType;
        arrayObj["carriageOrder"] = trainInfo.strOrder;
        arrayObj["steel"] = trainInfo.strRfidInfo;

        Json::Value trainParams;
        trainParams["poundNo"] = std::to_string(this->baseConfig_.trackName);
        arrayObj["trainParams"] = trainParams;
        Json::StreamWriterBuilder writer;
        std::string str = Json::writeString(writer, arrayObj);

        this->InfoSignals("第" + QString::fromStdString(trainInfo.strOrder) + "节，发送web: " + QString::fromStdString(str));
        httplib::Client cli(this->interfaceConfig_.httpIp.toStdString(), this->interfaceConfig_.httpPort);

        cli.set_connection_timeout(3, 0);
        cli.set_read_timeout(3, 0);
        httplib::Headers header;
        httplib::Params params;
        header.emplace("blade-auth", this->webToken);
        //header.emplace("Content-Type", "application/json");

        auto res = cli.Post(this->interfaceConfig_.upResultPath.toStdString(), header, str, "application/json");

        if (res)
        {
            if (res->status == 200)
            {
                this->InfoSignals("第" + QString::fromStdString(trainInfo.strOrder) + "节，web返回: " + QString::fromStdString(res->body));
                Json::CharReaderBuilder readerBuilder;
                std::istringstream iss(res->body);
                Json::Value root;
                std::string errs;
                bool parsingSuccessful = Json::parseFromStream(readerBuilder, iss, &root, &errs);
                if (parsingSuccessful)
                {
                    if (root["success"].asBool())
                    {
                        return true;
                    }
                    else
                    {

                        if (root["msg"].asString() == "请求未授权") {
                            this->WarnSignals("第" + QString::fromStdString(trainInfo.strOrder) + "节，因请求未授权，而上传识别结果失败！重新请求token。");
                            if (!this->getToken()) return false;
                            return this->upWeb(trainInfo);
                        }
                        this->ErrorSignals("第" + QString::fromStdString(trainInfo.strOrder) + "节，识别结果上传失败，原因：" + QString::fromStdString(root["msg"].asString()));
                    }
                }
                else
                {
                    this->ErrorSignals("第" + QString::fromStdString(trainInfo.strOrder) + "节，识别结果上传失败，返回数据解析异常，返回数据非json：" + QString::fromStdString(res->body));
                }
            }
            else
            {
                this->ErrorSignals("第" + QString::fromStdString(trainInfo.strOrder) + "节，识别结果上传失败，原因：" + QString::number(res->status) + " - " + QString::fromStdString(res->body));
                if (res->status == 401) {
                    this->WarnSignals("因请求未授权，而上传识别结果失败！重新请求token。");
                    this->getToken();
                    return this->upWeb(trainInfo);
                }
            }
        }
        else
        {
            this->ErrorSignals("第" + QString::fromStdString(trainInfo.strOrder) + "节，上传数据失败，请检查网络，或者上传地址！");
        }
    }
    catch (std::exception &e)
    {
        this->ErrorSignals("第" + QString::fromStdString(trainInfo.strOrder) + "节，上传识别结果失败,原因：" + QString::fromStdString(e.what()));
    }
    return false;
}

/**
 * @brief:Http获取授权
 * @param：
 * @return:
 */
bool UpResultThread::getToken()
{
    try
    {
        httplib::Client cli(this->interfaceConfig_.httpIp.toStdString(), this->interfaceConfig_.httpPort);
        cli.set_connection_timeout(0, 300 * 1000);
        cli.set_read_timeout(0,300*1000);
        httplib::Headers header;
        httplib::Params params;

        header.emplace("Authorization", "Basic Y2xpZW50X2VudGVycHJpc2U6Y2xpZW50X2VudGVycHJpc2Vfc2VjcmV0");

        params.emplace("username", this->interfaceConfig_.username.toStdString());
        params.emplace("password", this->interfaceConfig_.password.toStdString());
        params.emplace("tenantId", "000000");
        params.emplace("grant_type", "password");
        auto res = cli.Post("/api/blade-auth/oauth/token", header, params);
        if (res)
        {
            if (res->status == 200)
            {
                Json::CharReaderBuilder readerBuilder;
                std::istringstream iss(res->body);
                Json::Value root;
                std::string errs;
                bool parsingSuccessful = Json::parseFromStream(readerBuilder, iss, &root, &errs);

                if (parsingSuccessful)
                {
                    if (!root.get("token_type", "").asString().empty())
                    {
                        this->webToken = root["token_type"].asString();
                        this->webToken.append(" ");
                        this->webToken.append(root["access_token"].asString());
                        this->InfoSignals("已获取到web token");
                        return true;
                    }
                    else
                    {
                        this->ErrorSignals("获取web token失败，原因：" + QString::fromStdString(res->body));
                    }
                }
                else
                {
                    this->ErrorSignals("获取web token返回数据解析异常，返回数据非json。详细：" + QString::fromStdString(res->body));
                }
            }
        }
        else
        {
            auto err = res.error();
//            if (err == httplib::Error::Connection) {
//                std::cout << "   (连接出错)" << std::endl;
//            }
            this->ErrorSignals("获取web token失败！请检查网络或请求地址。详细：" + QString::fromStdString(to_string(err)));
        }
    }
    catch (std::exception &e)
    {
        this->ErrorSignals("获取授权失败,原因：" + QString::fromStdString(e.what()));
    }
    return false;
}

