#include "SubControlEngine.h"


using namespace ai_matrix;

SubControlEngine::SubControlEngine() {}

SubControlEngine::~SubControlEngine() {}

APP_ERROR SubControlEngine::Init()
{
    bUseEngine_ = true;
    dataSourceConfig_ = MyYaml::GetIns()->GetDataSourceConfigById(engineId_); //获取摄像机参数
    if (!dataSourceConfig_.bUse)
    {
        bUseEngine_ = false;
        LogWarn << "engineId_:" << engineId_ << " not use engine";
        return APP_ERR_OK;
    }
    bHwDecode_ = MyYaml::GetIns()->GetBoolValue("gc_hardware_decode");//硬解码
    
    strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0";
    strPort1_ = engineName_ + "_" + std::to_string(engineId_) + "_1";
    strPort2_ = engineName_ + "_" + std::to_string(engineId_) + "_2";
    bCollectDataFlag_ = MyYaml::GetIns()->GetBoolValue("gc_collect_data_flag");
    bPushActualFlag_ = MyYaml::GetIns()->GetBoolValue("gc_push_actual_flag");
    strCollectDataSavePath_ = MyYaml::GetIns()->GetPathValue("gc_collect_data_savepath");
    strResultPath_ = MyYaml::GetIns()->GetPathValue("gc_result_path");

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

APP_ERROR SubControlEngine::DeInit()
{
    if (!bUseEngine_)
    {
        LogWarn << "engineId_:" << engineId_ << " not use engine";
        return APP_ERR_OK;
    }

    LogInfo << "SubControlEngine DeInit ok";
    return APP_ERR_OK;
}

/**
* 参数初始化(列车结束时需调用)
* inParam : N/A
* outParam: N/A
* return  : N/A
*/
void SubControlEngine::InitParam()
{
    iPushDataNO_ = 1;
    moveData_.i64TimeStamp = 0;
    moveData_.bHasTrain = false;
    moveData_.bIsEnd = false;
    moveData_.strTrainDate = "";
    moveData_.strTrainName = "";
    moveData_.iFrameId = 1;
}

APP_ERROR SubControlEngine::Process()
{
    if (!bUseEngine_)
    {
        LogWarn << "engineId_:" << engineId_ << " not use engine";
        return APP_ERR_OK;
    }

    int iRet = APP_ERR_OK;
    while (!isStop_)
    {
        //pop端口0，解码后数据
        std::shared_ptr<void> pVoidData0 = nullptr;
        inputQueMap_[strPort0_]->pop(pVoidData0);
        if (nullptr == pVoidData0)
        {
            usleep(1000); //1ms
            continue;
        }

        //获取主摄像头检测的状态
        std::shared_ptr<void> pVoidData1 = nullptr;
        iRet = inputQueMap_[strPort1_]->pop(pVoidData1);
        if (nullptr != pVoidData1)
        {
            std::shared_ptr<MoveData> pMoveData = std::static_pointer_cast<MoveData>(pVoidData1);
            moveData_ = *pMoveData;
            LogDebug << "engineId:" << engineId_ << " trainname:" << moveData_.strTrainName
                     << " MoveData frameid:" << moveData_.iFrameId << " direction:" << moveData_.iDirection
                     << " IsEnd:" << moveData_.bIsEnd;
        }

        std::shared_ptr<ProcessData> pProcessDataTemp = std::static_pointer_cast<ProcessData>(pVoidData0);
        queueProcessData_.push(pProcessDataTemp);

        //1. 无车丢弃多余的数据，(只保留2s,50个数据)
        if (!moveData_.bHasTrain)
        {
            while (queueProcessData_.size() > 50)
            {
                queueProcessData_.pop();
            }
            continue;
        }

        //2. 有车获取解码数据处理
        if (queueProcessData_.empty())
        {
            continue;
        }
        std::shared_ptr<ProcessData> pProcessData = queueProcessData_.front();
        queueProcessData_.pop();

        bool bContinueFlag = false;
        while (!moveData_.bIsEnd && pProcessData->i64TimeStamp < moveData_.i64TimeStamp)    //获取和来车时间最接近的数据
        {
            if (queueProcessData_.empty())
            {
                bContinueFlag = true;
                LogWarn << "engineId:" << engineId_ << " no fit data  oldFrameTimeStamp:" << pProcessData->i64TimeStamp << " rePush.";
                queueProcessData_.push(pProcessData);
                break;
            }

            if (queueProcessData_.front()->i64TimeStamp > moveData_.i64TimeStamp)
            {
                if (moveData_.i64TimeStamp - pProcessData->i64TimeStamp > queueProcessData_.front()->i64TimeStamp - moveData_.i64TimeStamp)
                {
                    LogDebug << "oldFrameTimeStamp: " << pProcessData->i64TimeStamp << " newFrameTimeStamp:" << queueProcessData_.front()->i64TimeStamp;
                    pProcessData = queueProcessData_.front();
                    queueProcessData_.pop();
                }
                break;
            }
            pProcessData = queueProcessData_.front();
            queueProcessData_.pop();
        }
        if (bContinueFlag)
        {
            continue;
        }

        //3.构造过车存图数据，重置帧号 push 过车存图
        std::shared_ptr<SaveImgData> pSaveImgData = std::make_shared<SaveImgData>();
        pSaveImgData->iFrameId = iPushDataNO_ * dataSourceConfig_.iSkipInterval; //帧号
        pSaveImgData->pData = pProcessData->pData;
        pSaveImgData->iSize = pProcessData->iSize;
        pSaveImgData->iWidth = pProcessData->iWidth;
        pSaveImgData->iHeight = pProcessData->iHeight;
        char szCameraNo[4] = {0};
        sprintf(szCameraNo, "%03d", pProcessData->iDataSource + 1);
        pSaveImgData->strImgPath = strResultPath_ + moveData_.strTrainDate + "/" + moveData_.strTrainName + "/" + szCameraNo;
        pSaveImgData->strImgName = std::to_string(pSaveImgData->iFrameId) + ".jpg";
        pSaveImgData->bIsEnd = moveData_.bIsEnd;
        pSaveImgData->bSaveToFtp = true;
        pSaveImgData->i64TimeStamp = pProcessData->i64TimeStamp;
        pSaveImgData->iDirection = moveData_.iDirection;
        
        outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pSaveImgData));
        iPushDataNO_++;
        if ((moveData_.bIsEnd) && (moveData_.iFrameId <= pSaveImgData->iFrameId))
        {
            InitParam();
        }

        //4.图片采集
        if (bCollectDataFlag_)
        {
            //组织数据 push端口0 存图
            std::shared_ptr<SaveImgData> pSaveImgData = std::make_shared<SaveImgData>();
            pSaveImgData->iFrameId = pProcessData->iFrameId; //帧号
            char szCameraNo[4] = {0};
            sprintf(szCameraNo, "%03d", pProcessData->iDataSource + 1);
            pSaveImgData->strImgPath = strCollectDataSavePath_ + szCameraNo;
            pSaveImgData->strImgName = std::to_string(pSaveImgData->iFrameId);
            pSaveImgData->strImgName += "_";
            pSaveImgData->strImgName += std::to_string(pProcessData->i64TimeStamp);
            pSaveImgData->strImgName += ".jpg";
            iRet = outputQueMap_[strPort1_]->push(std::static_pointer_cast<void>(pSaveImgData));
        }

        //5.直播推流
        if(bPushActualFlag_)
        {
            //发送推流Egnine
            //iRet = outputQueMap_[strPort2_]->push(std::static_pointer_cast<void>(pProcessData));
        }
    }
    return APP_ERR_OK;
}
