#include "PostTrainAnaEngine.h"

using namespace ai_matrix;

PostTrainAnaEngine::PostTrainAnaEngine() {}

PostTrainAnaEngine::~PostTrainAnaEngine() {}

APP_ERROR PostTrainAnaEngine::Init()
{
    strPort0_ = engineName_ + "_" + std::to_string(engineId_) + "_0";
    strResultPath_ = MyYaml::GetIns()->GetPathValue("gc_result_path");
    std::map<int, ai_matrix::DataSourceConfig> mapUseDataSouceCfg = MyYaml::GetIns()->GetUseDataSourceConfig();

    for (auto iter = mapUseDataSouceCfg.begin(); iter != mapUseDataSouceCfg.end(); iter++)
    {
        //端口0是主摄像头push存图，需给其他使用的数据源push(来车/结束)通知
        if (iter->first != 0)
        {
            setPushPort_.insert(iter->first);
        }
        else
        {
            dataSourceCfg_ = iter->second;
        }
    }
    InitParam();
    LogInfo << "PostTrainAnaEngine Init ok";
    return APP_ERR_OK;
}

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


/**
* 参数初始化(列车结束时需调用)
* inParam : N/A
* outParam: N/A
* return  : N/A
*/
void PostTrainAnaEngine::InitParam()
{
    iMoveDataNO_ = dataSourceCfg_.iSkipInterval;
}

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

        std::shared_ptr<DecodedData> pDecodedData = std::static_pointer_cast<DecodedData>(pVoidData0);
        if (pDecodedData->iStatus == TRAINSTATUS_NO && !pDecodedData->bIsEnd)
        {
            continue;
        }

        //组织数据, push其他端口 (只通知2次，车来一次，车结束一次)
        if (iMoveDataNO_ == dataSourceCfg_.iSkipInterval || pDecodedData->bIsEnd)
        {
            LogDebug << "traindate:" << pDecodedData->strTrainDate << " trainname:" << pDecodedData->strTrainName
                     << " frameid:" << iMoveDataNO_ << " isEnd:" << pDecodedData->bIsEnd;

            uint32_t iFrameId = iMoveDataNO_ / dataSourceCfg_.iSkipInterval * dataSourceCfg_.iSkipInterval;
            std::shared_ptr<MoveData> pMoveData = std::make_shared<MoveData>();
            pMoveData->iFrameId = iFrameId; //当前帧号
            pMoveData->i64TimeStamp = pDecodedData->i64TimeStamp;
            pMoveData->bHasTrain = true;
            pMoveData->bIsEnd = pDecodedData->bIsEnd;
            pMoveData->strTrainDate = pDecodedData->strTrainDate;
            pMoveData->strTrainName =  pDecodedData->strTrainName;
            pMoveData->iDirection = pDecodedData->iDirection;
            for (auto iter = setPushPort_.begin(); iter != setPushPort_.end(); iter++)
            {
                outputQueMap_[engineName_ + "_" + std::to_string(engineId_) + "_" + std::to_string(*iter)]->push(std::static_pointer_cast<void>(pMoveData));
            }
            outputQueMap_[engineName_ + "_" + std::to_string(engineId_) + "_5"]->push(std::static_pointer_cast<void>(pMoveData));
        }

        //跳帧 存图
        if (iMoveDataNO_ % dataSourceCfg_.iSkipInterval == 0 || pDecodedData->bIsEnd)
        {
            // push端口,存图
            std::shared_ptr<SaveImgData> pSaveImgData = std::make_shared<SaveImgData>();
            pSaveImgData->pDecodeData = pDecodedData;
            pSaveImgData->iFrameId = iMoveDataNO_; //帧号
            char szCameraNo[4] = {0};
            sprintf(szCameraNo, "%03d", pDecodedData->iDataSource + 1);
            pSaveImgData->strImgPath = strResultPath_ + pDecodedData->strTrainDate + "/" + pDecodedData->strTrainName + "/" + szCameraNo;
            pSaveImgData->strImgName = std::to_string(pSaveImgData->iFrameId) + ".jpg";
            pSaveImgData->bIsEnd = pDecodedData->bIsEnd;
            pSaveImgData->bSaveToFtp = true;
            pSaveImgData->i64TimeStamp = pDecodedData->i64TimeStamp;
            pSaveImgData->iDirection = pDecodedData->iDirection;
            iRet = outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pSaveImgData));
        }

        iMoveDataNO_++;

        //结束帧或停车时需重新初始化相关信息
        if (pDecodedData->bIsEnd)
        {
            InitParam();
        }
    }
    return APP_ERR_OK;
}
