/**
 *
 * @author    seagle
 * @date      2025-3-21
 * @Description 
 *   Replace old EV
 */  
#include"TcPch.h"
#pragma hdrstop

#include"errcode.h"
#include"EV.h"
#include"Dictionary.h"
#include"Fields.h"
#include"stdarg.h"
#include"debug.h"
//#include"public.h"
//#include"SC.h"
static char envString[MAX_CONTEXT_LEN];
char* CEV::parseErrCode(const char* errCode, const char* envFormat, ...) {
    va_list args;
    va_start(args, envFormat);
    vsnprintf(envString, sizeof(envString) - 1, envFormat, args);
    va_end(args);
    char *ret=parseErrCodeV(errCode, envString);
    return ret;
}

char* CEV::parseErrCodeV(const char* errCode, const char * envString) {
    static char returnString[MAX_CONTEXT_LEN];
    
    returnString[0] = '\0';
   
    if (envString != NULL && envString[0] != '\0') {
        size_t findCommIndex = 0;
        size_t lastCommIndexPlus1 = 0;
        size_t envLen = strlen(envString);
        static Fields<MAX_PARAM_COUNT> envFields;
        envFields.clear();
        envFields.parse(envString, ';');

        size_t findLeft = 0;
        size_t findRight = 0;
        size_t lastFindRightPlus2 = 0;
        size_t codeLen = strlen(errCode);
        size_t returnLength = 0;
        for (findLeft = 0; findLeft < codeLen; findLeft++) {
            if (errCode[findLeft] == '{' && errCode[findLeft + 1] == '{') {
                for (findRight = findLeft + 2; findRight < codeLen; findRight++) {
                    if (errCode[findRight] == '}' && errCode[findRight + 1] == '}') {
                        //found left and right
                        if (returnLength + findLeft - lastFindRightPlus2 >= MAX_CONTEXT_LEN) {
                            return returnString;
                        }
                        memcpy(returnString+returnLength, errCode + lastFindRightPlus2, findLeft - lastFindRightPlus2);
                        returnLength+= findLeft - lastFindRightPlus2;
                        returnString[returnLength] = '\0';
                        static char key[MAX_NAME_LEN];
                        if (findRight - findLeft - 2 >= MAX_NAME_LEN) {
                            return returnString;
                        }
                        memcpy(key,errCode + findLeft + 2, findRight - findLeft - 2);
                        key[findRight - findLeft - 2] = '\0';
                        char* value = envFields.getValue(key);
                        if (value != NULL) {
                            size_t valueLength = strlen(value);
                            if (returnLength + valueLength > MAX_CONTEXT_LEN) {
                                return returnString;
                            }
                            memcpy(returnString+returnLength, value,valueLength);
                            returnLength += valueLength;
                            returnString[returnLength] = '\0';
                        }                        
                        lastFindRightPlus2 = findRight + 2;
                        findLeft = findRight + 1;
                        break;
                    }
                }
                if (findRight >= codeLen) {
                    //In the last,can not find }}
                    break;
                }


            }

        }
        if (findLeft - lastFindRightPlus2 > 0) {
            memcpy(returnString + returnLength, errCode + lastFindRightPlus2, findLeft - lastFindRightPlus2);
            returnLength += findLeft - lastFindRightPlus2;
            returnString[returnLength] = '\0';
        }
        return returnString;

    }
    strcpy (returnString, errCode);
    return returnString;
}
void CEV::postAlarmLog(const char* message){
     
    alarmLogIndex=(alarmLogIndex+1)%ALARM_LOG_BUFFER_COUNT;
    strcpy (alarmLog[alarmLogIndex], message);
    if(!SC->getBoolValue("alarmReady")){
        //pc read over
        alarmBufferIndex=(alarmBufferIndex+1)%ALARM_LOG_BUFFER_COUNT;
        SC->setBoolValue("alarmReady",TRUE);
        SC->setStringValue("alarmText",alarmLog[alarmBufferIndex]);
    }else{
        //pc not read
        if(alarmLogIndex==alarmBufferIndex){
            //overwrite
            alarmBufferIndex=(alarmBufferIndex+1)%ALARM_LOG_BUFFER_COUNT;
        }
    }
    hasAlarm = TRUE;
    
    //record log
    postInfoLog(message);

}
void CEV::postAlarmLog(const char* errCode, const char* envFormat,...)
{
    va_list args;
    va_start(args, envFormat);
    vsnprintf(envString, sizeof(envString) - 1, envFormat, args);
    va_end(args);
    char* ret = parseErrCodeV(errCode, envString);
    postAlarmLog(ret);
}
void CEV::postWarningLog(const char* message){
    warningLogIndex=(warningLogIndex+1)%WARNING_LOG_BUFFER_COUNT;
    strcpy (warningLog[warningLogIndex], message);
    if(!SC->getBoolValue("warningReady")){
        //has read by pc
        warningBufferIndex=(warningBufferIndex+1)%WARNING_LOG_BUFFER_COUNT;
        SC->setBoolValue("warningReady",TRUE);
        SC->setStringValue("warningText",warningLog[warningBufferIndex]);

    }else{
        //not read by pc
        if(warningLogIndex==warningBufferIndex){
            //overwrite
            warningBufferIndex=(warningBufferIndex+1)%WARNING_LOG_BUFFER_COUNT;
        }
    }
    
    //record log
    postInfoLog(message);
}

void CEV::postWarningLog(const char* errCode, const char *envFormat,...)
{
    va_list args;
    va_start(args, envFormat);
    vsnprintf(envString, sizeof(envString) - 1, envFormat, args);
    va_end(args);
    char* ret = parseErrCodeV(errCode, envString);
    postWarningLog(ret);
}
void CEV::clear(){
    SC->setBoolValue("alarmReady",FALSE);
    SC->setBoolValue("warningReady",FALSE);
    alarmLogIndex=-1;
	alarmBufferIndex=-1;
    warningLogIndex=-1;
	warningBufferIndex=-1;
    hasAlarm = FALSE;
}
void CEV::postInfoLog(const char* message,...){
    static char outputBuf[MAX_CONTEXT_LEN];
    va_list args;
    va_start(args, message);
    vsnprintf(outputBuf, sizeof(outputBuf) - 1, message,args);
    va_end(args);
    logger->info(outputBuf);
}

CEV* EV;
