/* Copyright (C) CENOS, Ltd - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Vadims Geza <vg@cenos-platform.com>, January 2020
*/

#include <iostream>
#include <regex>
#include "GetdpOutputAnalyzer.hpp"

GetdpOutputAnalyzer::GetdpOutputAnalyzer(MessageQueue_ messageQueue_) : OutputAnalyzer(messageQueue_)
{

}

messagedata GetdpOutputAnalyzer::Analyze(std::string input)
{
    for (auto regObj : regexJson)
    {
        std::smatch m;
        auto str = regObj["regex"].get<std::string>();
        std::regex e(str);
        std::regex_search(input, m, e);
        if (!m.empty())
        {
            std::string strToReturn = regObj["output"].get<std::string>();
            for (size_t i = 0; i < m.size(); i++)
            {
                if (strToReturn.find("#" + std::to_string(i+1)) != std::string::npos)
                    strToReturn.replace(strToReturn.find("#" + std::to_string(i+1)), 2, m[i+1]);
            }
            if (regObj["type"].get<std::string>() == "log")
            {
                messagedata retData(messagedata::info_lvl, messagedata::log, strToReturn);
                messageQueue->push(retData);
                return retData;
            }
            else if (regObj["type"].get<std::string>() == "error")
            {
                messagedata retData(messagedata::error, messagedata::response, strToReturn);
                return retData;
            }
            else if (regObj["type"].get<std::string>() == "warning")
            {
                messagedata retData(messagedata::warn_lvl, messagedata::log, strToReturn);
                messageQueue->push(retData);
                return retData;
            }


        }  
    }
    return messagedata(); 
}

messagedata GetdpOutputAnalyzer::AddToBuffer(char* buf)
{
    if (buf == nullptr)
        return messagedata();

    std::string inputStr(buf);
    bufferedString = bufferedString + inputStr;

    auto found = bufferedString.find_first_of("\r\n");
    while (found != std::string::npos)
    {
        if (found != std::string::npos)
        {
            std::string toAnalyze = bufferedString.substr(0, found);
            messagedata analyzedData = Analyze(toAnalyze);
            if (analyzedData.isDefined)
            {
                if (analyzedData.msgStatus == messagedata::error)
                    return analyzedData;
            }
            bufferedString = bufferedString.substr(found+1, std::string::npos);
            found = bufferedString.find_first_of("\r\n");
        }
        else
        {
            return messagedata();
        }

    }


    return messagedata();
}


/*
size_t foundTime = tempStr.find("Info    : Theta");
size_t foundAdaptiveTime = tempStr.find("Info    : Time step");
size_t foundSolveJac = tempStr.find("SolveJac[resol_");
size_t foundNonlinear = tempStr.find("Nonlinear Residual norm");
size_t foundConverged = tempStr.find("IterativeLoop converged");
size_t foundNotConverged = tempStr.find("IterativeLoop did NOT converge");
size_t foundConvergedN = tempStr.find("IterativeLoopN converged");
size_t foundNotConvergedN = tempStr.find("IterativeLoopN did NOT converge");
size_t foundNonlinearN = tempStr.find("IterativeLoopN: ");
size_t foundChangeCheck = tempStr.find("Maximal ");
size_t foundAccumulatedChangeCheck = tempStr.find("Accumulated ");
size_t foundSkippingSteps = tempStr.find("Skipping ");

*/