#include "ControlEngine.h"


using namespace ai_matrix;

ControlEngine::ControlEngine() {}

ControlEngine::~ControlEngine() {}

APP_ERROR ControlEngine::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";
    bCommandFlag_ = (MyYaml::GetIns()->GetStringValue("gc_run_mode") == "command");
    bCollectDataFlag_ = MyYaml::GetIns()->GetBoolValue("gc_collect_data_flag");
    strCollectDataSavePath_ = MyYaml::GetIns()->GetPathValue("gc_collect_data_savepath");
    bPushActualFlag_ = MyYaml::GetIns()->GetBoolValue("gc_push_actual_flag");

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

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

/**
* 获取检测状态
* inParam : N/A 
* outParam: N/A
* return  : N/A
*/
void ControlEngine::GetDetectState()
{
    // 1.一直识别模式
    if (!bCommandFlag_)
    {
        iStepInter_ = 1;
        return;
    }

    //2.命令触发识别模式
    int iRet = APP_ERR_OK;
    std::shared_ptr<void> pVoidData1 = nullptr;
    iRet = inputQueMap_[strPort1_]->pop(pVoidData1);
    if (nullptr != pVoidData1)
    {
        std::shared_ptr<std::string> pstrCommand = std::static_pointer_cast<std::string>(pVoidData1);
        LogDebug << "recv Command:" << *pstrCommand;

        if ((*pstrCommand) == "start")
        {
            iStepInter_ = 1;
        }
        else if ((*pstrCommand) == "end")
        {
            if (iStepInter_ == 1)
            {
                iStepInter_ = 2;
            }
            else
            {
                LogError << "command:end is worng";
            }            
        }
    }

    //未接受到新命令，按上次命令结果返回
}

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

    int iRet = APP_ERR_OK;
    while (!isStop_)
    {
        //获取识别状态
        GetDetectState();

        //pop端口0，解码后数据
        std::shared_ptr<void> pVoidData0 = nullptr;
        inputQueMap_[strPort0_]->pop(pVoidData0);
        if (nullptr == pVoidData0)
        {
            usleep(1000); //1ms
            continue;
        }
       
        std::shared_ptr<ProcessData> pProcessData = std::static_pointer_cast<ProcessData>(pVoidData0);
		
        //1. 识别处理
        if (iStepInter_ !=  0)
        {
            pProcessData->iStatus = TRAINSTATUS_RUN;
            pProcessData->bIsEnd = ((iStepInter_ == 2) ? true : false);
            
            iRet = outputQueMap_[strPort0_]->push(std::static_pointer_cast<void>(pProcessData));
            if (iStepInter_ == 2)
            {
                iStepInter_ = 0;
            }
        }

        //2.图片采集
        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));
            continue;
        }

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