//
// Created by nvidia on 24-10-14.
//

#include "SaveDebugImageEngine.h"

using namespace ai_matrix;

SaveDebugImageEngine::SaveDebugImageEngine() {}

SaveDebugImageEngine::~SaveDebugImageEngine() {}

APP_ERROR SaveDebugImageEngine::Init()
{

    strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0";

    this->baseConfig_ = Config::getins()->getBaseConfig();
    vecCompressionParams_.push_back(cv::IMWRITE_JPEG_QUALITY);  //选择jpeg
    vecCompressionParams_.push_back(this->iPicQuality_);        //图片质量

    LogInfo << "SaveDebugImageEngine Init ok";
    return APP_ERR_OK;
}

APP_ERROR SaveDebugImageEngine::DeInit()
{
    LogInfo << "SaveDebugImageEngine DeInit ok";
    return APP_ERR_OK;
}

APP_ERROR SaveDebugImageEngine::Process()
{
    int iRet = APP_ERR_OK;
    while (!isStop_)
    {
        std::shared_ptr<void> pvoidd = nullptr;
        inputQueMap_[strPort0_]->pop(pvoidd);
        if (nullptr == pvoidd)
        {
            usleep(1000);
            continue;
        }

        std::shared_ptr<VStep2OutputData> pVStep2OutputData = std::static_pointer_cast<VStep2OutputData>(pvoidd);

        if (pVStep2OutputData->cvImage.empty())
        {
            LogWarn << " 帧:" << pVStep2OutputData->iFrameId << " 数据源:" << pVStep2OutputData->iDataSource << " debug图像为空";
            continue;
        }
        cv::Mat image = pVStep2OutputData->cvImage.clone();

        std::string strDataDir = this->baseConfig_.strDebugResultPath + "/"
                                 + pVStep2OutputData->strDetectDate + "/"
                                 + StringUtil::getins()->replace_all_distinct(pVStep2OutputData->strDetectTime, ":", "-")
                                 + "/";

        std::string strJsonPath = strDataDir
                + std::to_string(pVStep2OutputData->iFrameId)
                + "_"
                + std::to_string(pVStep2OutputData->iDataSource) + ".json";
        std::string strImagePath = strDataDir
                + std::to_string(pVStep2OutputData->iFrameId)
                + "_"
                + std::to_string(pVStep2OutputData->iDataSource) + ".jpg";

        Json::Value jvFrameInfo;
        if (!FileUtil::getins()->readJsonInfo(jvFrameInfo, strJsonPath))
        {
            continue;
        }

//        cv::Mat image = cv::imread(strImagePath);

        if (image.empty())
        {
//            LogWarn << " 帧:" << pVStep2OutputData->iFrameId << " 数据源:" << pVStep2OutputData->iDataSource << " debug图像未找到";
            continue;
        }

        if (this->baseConfig_.bTestModel)
        {
//            std::stringstream ss;
            std::vector<std::string> vecTitle;
            vecTitle.emplace_back("FrameID:" + to_string(pVStep2OutputData->iFrameId));
            vecTitle.emplace_back("TimeStamp:" + jvFrameInfo["timeStamp"].asString());

            int base_line = 0;
            cv::Point text_org(15, 45); // 文本起始点
            for (const auto & i : vecTitle)
            {
                cv::Size text_size = cv::getTextSize(i, cv::FONT_HERSHEY_SIMPLEX, 1, 2, 0);
                cv::Point baseline_loc(text_org);
                baseline_loc.y += base_line + text_size.height;
                cv::putText(image, i, baseline_loc, cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 0, 255), 2);
                // 手动调整x位置，为下一个单词留出空间
                text_org.x += text_size.width + 10;
                text_org.x = text_org.x > IMAGE_WIDTH ? 15 : text_org.x;
                base_line++;
            }

            cv::Scalar cvScalar = {0, 255, 0, 255};

            float centerX = pVStep2OutputData->step2ResultData.fLTX + (pVStep2OutputData->step2ResultData.fRBX - pVStep2OutputData->step2ResultData.fLTX)/2;
            float centerY = pVStep2OutputData->step2ResultData.fLTY + (pVStep2OutputData->step2ResultData.fRBY - pVStep2OutputData->step2ResultData.fLTY)/2;
//        auto start = std::chrono::system_clock::now();  //计时开始
            cv::rectangle(image,
                          cv::Point(pVStep2OutputData->step2ResultData.fLTX, pVStep2OutputData->step2ResultData.fLTY),
                          cv::Point(pVStep2OutputData->step2ResultData.fRBX, pVStep2OutputData->step2ResultData.fRBY),
                          cvScalar, 2);
            cv::line(image,
                     cv::Point(centerX, pVStep2OutputData->step2ResultData.fLTY-30), cv::Point(centerX, pVStep2OutputData->step2ResultData.fRBY+30),
                     cvScalar, 1);

            cv::Size text_size = cv::getTextSize(pVStep2OutputData->step2ResultData.transInfo.strTmpResult, cv::FONT_HERSHEY_SIMPLEX, 1, 2, 0);
            cv::Point linePoint(pVStep2OutputData->step2ResultData.fLTX, pVStep2OutputData->step2ResultData.fRBY + text_size.height + 5);
            cv::putText(image,
                        pVStep2OutputData->step2ResultData.transInfo.strTmpResult,
                        linePoint,
                        cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 255, 0, 180), 2);


            for (const auto &step2ResultData : pVStep2OutputData->vecCornerResultData)
            {
                cvScalar = {0, 255, 255, 255};
                float centerX_corner = step2ResultData.fLTX + (step2ResultData.fRBX - step2ResultData.fLTX)/2;
                cv::rectangle(image,
                              cv::Point(step2ResultData.fLTX, step2ResultData.fLTY),
                              cv::Point(step2ResultData.fRBX, step2ResultData.fRBY),
                              cvScalar, 2);
                cv::line(image,
                         cv::Point(centerX_corner, step2ResultData.fLTY-30), cv::Point(centerX_corner, step2ResultData.fRBY+30),
                         cvScalar, 1);
            }
        }

//        auto end = std::chrono::system_clock::now();
//        LogDebug << "图片存储用时: " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms  " << strImagePath;

        if (!cv::imwrite(strImagePath, image, this->vecCompressionParams_))
        {
            LogError << "图片存储失败：" << strImagePath;
        }
//        else
//        {
//            LogInfo << "图片存储成功：" << strImagePath;
//        }

    }
    return APP_ERR_OK;
}