
#include "RestfulConverter.h"


char g_szProcessname[MAX_STRING_SIZE + 1];
char g_szProcessPath[PATH_MAX + 1];
char g_szBaseRestfulURL[MAX_STRING_SIZE + 1];
int g_nResponseTimeout;

int main(int argc, char *argv[])
{
    char szProcessname[PATH_MAX + 1];
    char *pFindPointer;
    //int nPathIndicatorPos;
    int nResult;

    DaemonStart();
    nResult = SafeStrCopy(szProcessname, sizeof(szProcessname), argv[0]);
    if (nResult != SEC_ERR_SUCCESS)
    {
        printf_s("strcpy_s Error![%d]\n", nResult);
    }
//    printf_s("Input argument : [%s]\n", argv[0]);
    pFindPointer = szProcessname;
    nResult = SafeStrrChr(szProcessname, strnlen_s(szProcessname, sizeof(szProcessname)), PATH_SEPERATOR, &pFindPointer);

//    printf_s("문자열길이 : %d\n", strnlen_s(szProcessname, sizeof(szProcessname)));
//    printf_s("szProcessname Address : %x\n", szProcessname);
//    printf_s("pFindPointer Address : %x\n", pFindPointer);
//    printf_s("szProcess Name : %s\n", szProcessname);
//    printf_s("g_szProcess Name : %s\n", g_szProcessname);

//    if (nResult != EOK)
//    {
//        printf_s("strrchr_s Error![%d]\n", nResult);
//    }

    if (pFindPointer == NULL)
    {
        nResult = SafeStrCopy(g_szProcessname, sizeof(g_szProcessname), szProcessname);
    }
    else
    {
        nResult = SafeStrCopy(g_szProcessname, sizeof(g_szProcessname), pFindPointer + 1);
    }
//    printf_s("szProcess Name : %s\n", szProcessname);
//    printf_s("g_szProcess Name : %s\n", g_szProcessname);

    GetExecPath(g_szProcessPath, sizeof(g_szProcessPath) - 1, argv[0]);


    if (g_szProcessPath == NULL)
    {
        printf_s("Can't get process path[Cann't load config file]!\nExit Program!");
        return -1;
    }

    nResult = InitMessageProcessConfig();

    if (nResult != MQ_ERR_SUCCESS)
    {
        printf_s("Program terminated!!!\n");
        return -1;
    }

    WriteLog(LogType_SystemOut, LogLevel_Info, "Process Started![%s]", g_szProcessname);

    curl_global_init(CURL_GLOBAL_ALL);

    /* Socket 처리 루프 : 종료시 프로그램 종료됨 */
    nResult = InitThread(WorkThread);
    while(true)
    {
        sleep(5);
    }

    WriteLog(LogType_SystemOut, LogLevel_Info, "Process Stopped![%s]", g_szProcessname);

    return 0;

}


int InitMessageProcessConfig()
{
    char szConfigfilename[PATH_MAX + 1];
    char szConfigfilenameTemp[PATH_MAX + 1];
    char szValueTemp[MAX_STRING_SIZE + 1];
    int nResult;

//    snprintf(szConfigfilenameTemp, sizeof(szConfigfilenameTemp), "%s/%s/", g_szProcessPath, CONF_FILE_PATH);
//
//    realpath(szConfigfilenameTemp, szConfigfilename);
//
//    SafeStrCat(szConfigfilename, sizeof(szConfigfilename), "/", 1);
//    SafeStrCat(szConfigfilename, sizeof(szConfigfilename), g_szProcessname, strnlen_s(g_szProcessname, sizeof(g_szProcessname)));
//    SafeStrCat(szConfigfilename, sizeof(szConfigfilename), CONF_FILE_EXT, strnlen_s(CONF_FILE_EXT, sizeof(CONF_FILE_EXT)));
    snprintf(szConfigfilenameTemp, sizeof(szConfigfilenameTemp), "%s%c%s%c", g_szProcessPath, PATH_SEPERATOR, CONF_FILE_PATH, PATH_SEPERATOR);

    realpath(szConfigfilenameTemp, szConfigfilename);

    snprintf(szValueTemp, sizeof(szValueTemp), "%c", PATH_SEPERATOR);
    nResult = SafeStrCat(szConfigfilename, sizeof(szConfigfilename), szValueTemp, 1);
    nResult = SafeStrCat(szConfigfilename, sizeof(szConfigfilename), g_szProcessname, strnlen_s(g_szProcessname, sizeof(g_szProcessname)));
    nResult = SafeStrCat(szConfigfilename, sizeof(szConfigfilename), CONF_FILE_EXT, strnlen_s(CONF_FILE_EXT, sizeof(CONF_FILE_EXT)));

    printf_s("Process Name : %s\n", g_szProcessname);
    printf_s("Process Path : %s\n", g_szProcessPath);
    printf_s("Config Filename : %s\n", szConfigfilename);

    ReadConfigFile(true, szConfigfilename);

    if (InitLogConfig() != LOG_ERR_SUCCESS)
    {
        return MP_ERR_CONFIG;
    }

    if (GetConfigValue(RC_RESTFULAPI_BASE_URL_KEY, g_szBaseRestfulURL, sizeof(g_szBaseRestfulURL)) != CONF_ERR_SUCCESS)
    {
        WriteLog(LogType_ErrorOut, LogLevel_Error, "Socket RESTFULAPI_BASE_URL_KEY configuration not found!");
        return MP_ERR_CONFIG;
    }
    // Read RC_RESPONSE_TIMEOUT_KEY
    if (GetConfigValue(RC_RESPONSE_TIMEOUT_KEY, szValueTemp, sizeof(szValueTemp)) != CONF_ERR_SUCCESS)
    {
        WriteLog(LogType_ErrorOut, LogLevel_Error, "Socket MS_RESPONSE_TIMEOUT_KEY configuration not found!");
        return SOCK_ERR_CONFIG;
    }
    if (SafeStringToInt(szValueTemp, sizeof(szValueTemp), &g_nResponseTimeout) != CONF_ERR_SUCCESS)
    {
        WriteLog(LogType_ErrorOut, LogLevel_Error, "Socket MS_RESPONSE_TIMEOUT_KEY configuration error[ConfigFile:%s]!", szValueTemp);
        return SOCK_ERR_CONFIG;
    }


    if (InitProcessorMQConfig() != MQ_ERR_SUCCESS)
    {
        return MP_ERR_CONFIG;
    }

    if (InitThreadConfig() != THREAD_ERR_SUCCESS)
    {
        return MP_ERR_CONFIG;
    }

    return MP_ERR_SUCCESS;
}

void *WorkThread(void *pData)
{
    struct THREAD_INFO *pThreadInfo;
    amqp_rpc_reply_t sRPCReply;
    char szMessageBuffer[MAX_STRING_SIZE*10 + 1];
    int nResult;
    int *pnThreadExitCode;
    char szCorrelationID[MAX_STRING_SIZE + 1];
    char szReplyQueuename[MAX_STRING_SIZE + 1];
    char szExchangername[MAX_STRING_SIZE + 1];
    char szMessageID[MAX_STRING_SIZE + 1];
    char szSendMessageBuffer[MAX_STRING_SIZE + 1];
    char szRespDataBuffer[MAX_STRING_SIZE + 1];
    char szRespCode[sizeof(((struct MESSAGE_FRAME *)0)->szRespCode) + 1];
    int nMessageLength;
    int nCmpResult1;
    int nCmpResult2;
    uint64_t nDeliveryTag;
    struct timeval sGetMessageTimeout;

    struct MESSAGE_FRAME sReceiveMessageFrame;

    int nParsingOffset;

    CURL *pCurlContext;

    int (*MessageProcessFunction)(int nThreadIndex, CURL *pCurlContext, char *pRecvMessage, int nRecvMessageLength, char *pRespMessage, int nRespMessageLength, char *pRespCode);

    pThreadInfo = (struct THREAD_INFO *)pData;
    pnThreadExitCode = NULL;
    nResult = SafeMemoryAlloc((void **)&pnThreadExitCode, sizeof(int));
    //pnThreadExitCode = SafeAlloc(pnThreadExitCode, sizeof(int));
    *pnThreadExitCode = 0;
    sGetMessageTimeout.tv_sec = 0;
    sGetMessageTimeout.tv_usec = 1000;
    while (pThreadInfo->bThreadLoop)
    {
        if (pThreadInfo->sPublishMQ.bMQConnection == false || pThreadInfo->sPublishMQ.bMQChannelOpen == false
            || pThreadInfo->sConsumeMQ.bMQConnection == false || pThreadInfo->sConsumeMQ.bMQChannelOpen == false)
        {
            if (ConnectProcessorMQ(pThreadInfo, true) != MQ_ERR_SUCCESS)
            {
                WriteLog(LogType_StandardOut, LogLevel_Debug, "[Thread:%02d]ConnectProcessMQ is failed!", pThreadInfo->nThreadIndex);
                continue;
            }
            WriteLog(LogType_StandardOut, LogLevel_Debug, "[Thread:%02d]ConnectProcessMQ is succeeded!!", pThreadInfo->nThreadIndex);
        }
        //amqp_maybe_release_buffers(pThreadInfo->sMQConnectionState);
        //nResult = GetMessageFromQueue(pThreadInfo->sConsumeMQ.sMQConnectionState, szExchangername, sizeof(szExchangername), szMessageBuffer, sizeof(szMessageBuffer), szCorrelationID, sizeof(szCorrelationID), szReplyQueuename, sizeof(szReplyQueuename), &pThreadInfo->sConsumeMQ.bMQConnection, &pThreadInfo->sConsumeMQ.bMQChannelOpen, &nDeliveryTag, &sGetMessageTimeout);
		nResult = GetMessageFromQueue(pThreadInfo->sConsumeMQ.sMQConnectionState, szExchangername, sizeof(szExchangername), szMessageBuffer, sizeof(szMessageBuffer), szCorrelationID, sizeof(szCorrelationID), szReplyQueuename, sizeof(szReplyQueuename), &pThreadInfo->sConsumeMQ.bMQConnection, &pThreadInfo->sConsumeMQ.bMQChannelOpen, &nDeliveryTag, NULL);

        nMessageLength = strnlen_s(szMessageBuffer, sizeof(szMessageBuffer));
        if (nResult == MQ_ERR_SUCCESS)
        {
            //printf_s("Message Received : %s\n", szMessageBuffer);
            //WriteRawCommLog(LogType_CommOut, LogLevel_Info, pThreadInfo->nThreadIndex, 'C', "%s", szMessageBuffer);
            WriteQueueLog(LogType_MQOut, LogLevel_Info, pThreadInfo->nThreadIndex, 'C', g_szMQMessageRecvQueuename, "", szCorrelationID, nMessageLength, "%s", szMessageBuffer);
            WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]MQ Data Consume[Data:%s]!", pThreadInfo->nThreadIndex, szMessageBuffer);
            //nResult = PutAckMessageToQueue(pThreadInfo->sMQConnectionState, szCorrelationID, szReplyQueuename, szMessageBuffer, strnlen_s(szMessageBuffer, sizeof(szMessageBuffer)), &pThreadInfo->bMQConnection, &pThreadInfo->bChannelOpen);

            // 수신된 전문의 파싱
            nResult = SafeMemSet(&sReceiveMessageFrame, sizeof(sReceiveMessageFrame), 0, sizeof(sReceiveMessageFrame));
            nParsingOffset = 0;
            nResult = GetCheckedValue(TYPE_ALPHA_NUMERIC, &sReceiveMessageFrame.szMessageLength, sizeof(sReceiveMessageFrame.szMessageLength) - 1, szMessageBuffer + nParsingOffset);
            if (nResult != STR_ERR_SUCCESS)
            {
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Receive Data Parsing Error-[MessageLengthError:%-*.*s,Data:%s]!", pThreadInfo->nThreadIndex, sizeof(sizeof(sReceiveMessageFrame.szMessageLength) - 1), sizeof(sizeof(sReceiveMessageFrame.szMessageLength) - 1),  szMessageBuffer + nParsingOffset, szMessageBuffer);
                snprintf(szSendMessageBuffer, sizeof(szSendMessageBuffer), "%s%c%s%s%-8.8s%-14.14s%s%s", sReceiveMessageFrame.szOrganizationCode, sReceiveMessageFrame.cOccurType, sReceiveMessageFrame.szWorkType, sReceiveMessageFrame.szMsgType, sReceiveMessageFrame.szSerialNo, sReceiveMessageFrame.szRequestDateTime, GetSocketRespCode(RESP_FORMAT_ERROR), szMessageBuffer + MESSAGE_FRAME_SIZE);
                nResult = PutReplyMessageToQueue(pThreadInfo->sPublishMQ.sMQConnectionState, szCorrelationID, szReplyQueuename, szSendMessageBuffer, strnlen_s(szSendMessageBuffer, sizeof(szSendMessageBuffer)), &pThreadInfo->sPublishMQ.bMQConnection, &pThreadInfo->sPublishMQ.bMQChannelOpen);
                WriteQueueLog(LogType_MQOut, LogLevel_Info, pThreadInfo->nThreadIndex, 'P', "", szReplyQueuename, szCorrelationID, nMessageLength, "%s", szMessageBuffer);
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Send Response Publish[Queue:%s,UUID:%s,Data:%s]!", pThreadInfo->nThreadIndex, szReplyQueuename, szCorrelationID, szMessageBuffer);
                continue;
            }
            nParsingOffset += sizeof(sReceiveMessageFrame.szMessageLength) - 1;

            nResult = GetCheckedValue(TYPE_ALPHA_NUMERIC, &sReceiveMessageFrame.szOrganizationCode, sizeof(sReceiveMessageFrame.szOrganizationCode) - 1, szMessageBuffer + nParsingOffset);
            if (nResult != STR_ERR_SUCCESS)
            {
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Receive Data Parsing Error-[OraganizationCodeError:%-*.*s,Data:%s]!", pThreadInfo->nThreadIndex, sizeof(sizeof(sReceiveMessageFrame.szOrganizationCode) - 1), sizeof(sizeof(sReceiveMessageFrame.szOrganizationCode) - 1),  szMessageBuffer + nParsingOffset, szMessageBuffer);
                snprintf(szSendMessageBuffer, sizeof(szSendMessageBuffer), "%s%c%s%s%-8.8s%-14.14s%s%s", sReceiveMessageFrame.szOrganizationCode, sReceiveMessageFrame.cOccurType, sReceiveMessageFrame.szWorkType, sReceiveMessageFrame.szMsgType, sReceiveMessageFrame.szSerialNo, sReceiveMessageFrame.szRequestDateTime, GetSocketRespCode(RESP_FORMAT_ERROR), szMessageBuffer + MESSAGE_FRAME_SIZE);
                nResult = PutReplyMessageToQueue(pThreadInfo->sPublishMQ.sMQConnectionState, szCorrelationID, szReplyQueuename, szSendMessageBuffer, strnlen_s(szSendMessageBuffer, sizeof(szSendMessageBuffer)), &pThreadInfo->sPublishMQ.bMQConnection, &pThreadInfo->sPublishMQ.bMQChannelOpen);
                WriteQueueLog(LogType_MQOut, LogLevel_Info, pThreadInfo->nThreadIndex, 'P', "", szReplyQueuename, szCorrelationID, nMessageLength, "%s", szMessageBuffer);
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Send Response Publish[Queue:%s,UUID:%s,Data:%s]!", pThreadInfo->nThreadIndex, szReplyQueuename, szCorrelationID, szMessageBuffer);
                continue;
            }
            nParsingOffset += sizeof(sReceiveMessageFrame.szOrganizationCode) - 1;
            sReceiveMessageFrame.cOccurType = szMessageBuffer[nParsingOffset];
            if (sReceiveMessageFrame.cOccurType != 'C' && sReceiveMessageFrame.cOccurType != 'S')
            {
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Receive Data Parsing Error-[OccurTypeError:%c,Data:%s]!", pThreadInfo->nThreadIndex, sReceiveMessageFrame.cOccurType, szMessageBuffer);
                snprintf(szSendMessageBuffer, sizeof(szSendMessageBuffer), "%s%c%s%s%-8.8s%-14.14s%s%s", sReceiveMessageFrame.szOrganizationCode, sReceiveMessageFrame.cOccurType, sReceiveMessageFrame.szWorkType, sReceiveMessageFrame.szMsgType, sReceiveMessageFrame.szSerialNo, sReceiveMessageFrame.szRequestDateTime, GetSocketRespCode(RESP_FORMAT_ERROR), szMessageBuffer + MESSAGE_FRAME_SIZE);
                nResult = PutReplyMessageToQueue(pThreadInfo->sPublishMQ.sMQConnectionState, szCorrelationID, szReplyQueuename, szSendMessageBuffer, strnlen_s(szSendMessageBuffer, sizeof(szSendMessageBuffer)), &pThreadInfo->sPublishMQ.bMQConnection, &pThreadInfo->sPublishMQ.bMQChannelOpen);
                WriteQueueLog(LogType_MQOut, LogLevel_Info, pThreadInfo->nThreadIndex, 'P', "", szReplyQueuename, szCorrelationID, nMessageLength, "%s", szMessageBuffer);
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Send Response Publish[Queue:%s,UUID:%s,Data:%s]!", pThreadInfo->nThreadIndex, szReplyQueuename, szCorrelationID, szMessageBuffer);
                continue;
            }
            nParsingOffset++;
            nResult = GetCheckedValue(TYPE_ALPHA_NUMERIC, &sReceiveMessageFrame.szWorkType, sizeof(sReceiveMessageFrame.szWorkType) - 1, szMessageBuffer + nParsingOffset);
            if (nResult != STR_ERR_SUCCESS)
            {
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Receive Data Parsing Error-[WorkTypeError:%-*.*s,Data:%s]!", pThreadInfo->nThreadIndex, sizeof(sizeof(sReceiveMessageFrame.szWorkType) - 1), sizeof(sizeof(sReceiveMessageFrame.szWorkType) - 1),  szMessageBuffer + nParsingOffset, szMessageBuffer);
                snprintf(szSendMessageBuffer, sizeof(szSendMessageBuffer), "%s%c%s%s%-8.8s%-14.14s%s%s", sReceiveMessageFrame.szOrganizationCode, sReceiveMessageFrame.cOccurType, sReceiveMessageFrame.szWorkType, sReceiveMessageFrame.szMsgType, sReceiveMessageFrame.szSerialNo, sReceiveMessageFrame.szRequestDateTime, GetSocketRespCode(RESP_FORMAT_ERROR), szMessageBuffer + MESSAGE_FRAME_SIZE);
                nResult = PutReplyMessageToQueue(pThreadInfo->sPublishMQ.sMQConnectionState, szCorrelationID, szReplyQueuename, szSendMessageBuffer, strnlen_s(szSendMessageBuffer, sizeof(szSendMessageBuffer)), &pThreadInfo->sPublishMQ.bMQConnection, &pThreadInfo->sPublishMQ.bMQChannelOpen);
                WriteQueueLog(LogType_MQOut, LogLevel_Info, pThreadInfo->nThreadIndex, 'P', "", szReplyQueuename, szCorrelationID, nMessageLength, "%s", szMessageBuffer);
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Send Response Publish[Queue:%s,UUID:%s,Data:%s]!", pThreadInfo->nThreadIndex, szReplyQueuename, szCorrelationID, szMessageBuffer);
                continue;
            }
            nParsingOffset += sizeof(sReceiveMessageFrame.szWorkType) - 1;
            nResult = GetCheckedValue(TYPE_ALPHA_NUMERIC, &sReceiveMessageFrame.szMsgType, sizeof(sReceiveMessageFrame.szMsgType) - 1, szMessageBuffer + nParsingOffset);
            if (nResult != STR_ERR_SUCCESS)
            {
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Receive Data Parsing Error-[MsgTypeError:%-*.*s,Data:%s]!", pThreadInfo->nThreadIndex, sizeof(sizeof(sReceiveMessageFrame.szMsgType) - 1), sizeof(sizeof(sReceiveMessageFrame.szMsgType) - 1),  szMessageBuffer + nParsingOffset, szMessageBuffer);
                snprintf(szSendMessageBuffer, sizeof(szSendMessageBuffer), "%s%c%s%s%-8.8s%-14.14s%s%s", sReceiveMessageFrame.szOrganizationCode, sReceiveMessageFrame.cOccurType, sReceiveMessageFrame.szWorkType, sReceiveMessageFrame.szMsgType, sReceiveMessageFrame.szSerialNo, sReceiveMessageFrame.szRequestDateTime, GetSocketRespCode(RESP_FORMAT_ERROR), szMessageBuffer + MESSAGE_FRAME_SIZE);
                nResult = PutReplyMessageToQueue(pThreadInfo->sPublishMQ.sMQConnectionState, szCorrelationID, szReplyQueuename, szSendMessageBuffer, strnlen_s(szSendMessageBuffer, sizeof(szSendMessageBuffer)), &pThreadInfo->sPublishMQ.bMQConnection, &pThreadInfo->sPublishMQ.bMQChannelOpen);
                WriteQueueLog(LogType_MQOut, LogLevel_Info, pThreadInfo->nThreadIndex, 'P', "", szReplyQueuename, szCorrelationID, nMessageLength, "%s", szMessageBuffer);
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Send Response Publish[Queue:%s,UUID:%s,Data:%s]!", pThreadInfo->nThreadIndex, szReplyQueuename, szCorrelationID, szMessageBuffer);
                continue;
            }
            nParsingOffset += sizeof(sReceiveMessageFrame.szMsgType) - 1;
            nResult = GetCheckedValue(TYPE_ALPHA_NUMERIC, &sReceiveMessageFrame.szSerialNo, sizeof(sReceiveMessageFrame.szSerialNo) - 1, szMessageBuffer + nParsingOffset);
            if (nResult != STR_ERR_SUCCESS)
            {
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Receive Data Parsing Error-[SerialNoTypeError:%-*.*s,Data:%s]!", pThreadInfo->nThreadIndex, sizeof(sizeof(sReceiveMessageFrame.szSerialNo) - 1), sizeof(sizeof(sReceiveMessageFrame.szSerialNo) - 1),  szMessageBuffer + nParsingOffset, szMessageBuffer);
                snprintf(szSendMessageBuffer, sizeof(szSendMessageBuffer), "%s%c%s%s%-8.8s%-14.14s%s%s", sReceiveMessageFrame.szOrganizationCode, sReceiveMessageFrame.cOccurType, sReceiveMessageFrame.szWorkType, sReceiveMessageFrame.szMsgType, sReceiveMessageFrame.szSerialNo, sReceiveMessageFrame.szRequestDateTime, GetSocketRespCode(RESP_FORMAT_ERROR), szMessageBuffer + MESSAGE_FRAME_SIZE);
                nResult = PutReplyMessageToQueue(pThreadInfo->sPublishMQ.sMQConnectionState, szCorrelationID, szReplyQueuename, szSendMessageBuffer, strnlen_s(szSendMessageBuffer, sizeof(szSendMessageBuffer)), &pThreadInfo->sPublishMQ.bMQConnection, &pThreadInfo->sPublishMQ.bMQChannelOpen);
                WriteQueueLog(LogType_MQOut, LogLevel_Info, pThreadInfo->nThreadIndex, 'P', "", szReplyQueuename, szCorrelationID, nMessageLength, "%s", szMessageBuffer);
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Send Response Publish[Queue:%s,UUID:%s,Data:%s]!", pThreadInfo->nThreadIndex, szReplyQueuename, szCorrelationID, szMessageBuffer);
                continue;
            }
            nParsingOffset += sizeof(sReceiveMessageFrame.szSerialNo) - 1;
            nResult = GetCheckedValue(TYPE_ALPHA_NUMERIC, &sReceiveMessageFrame.szRequestDateTime, sizeof(sReceiveMessageFrame.szRequestDateTime) - 1, szMessageBuffer + nParsingOffset);
            if (nResult != STR_ERR_SUCCESS)
            {
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Receive Data Parsing Error-[RequestTimeError:%-*.*s,Data:%s]!", pThreadInfo->nThreadIndex, sizeof(sizeof(sReceiveMessageFrame.szRequestDateTime) - 1), sizeof(sizeof(sReceiveMessageFrame.szRequestDateTime) - 1),  szMessageBuffer + nParsingOffset, szMessageBuffer);
                snprintf(szSendMessageBuffer, sizeof(szSendMessageBuffer), "%s%c%s%s%-8.8s%-14.14s%s%s", sReceiveMessageFrame.szOrganizationCode, sReceiveMessageFrame.cOccurType, sReceiveMessageFrame.szWorkType, sReceiveMessageFrame.szMsgType, sReceiveMessageFrame.szSerialNo, sReceiveMessageFrame.szRequestDateTime, GetSocketRespCode(RESP_FORMAT_ERROR), szMessageBuffer + MESSAGE_FRAME_SIZE);
                nResult = PutReplyMessageToQueue(pThreadInfo->sPublishMQ.sMQConnectionState, szCorrelationID, szReplyQueuename, szSendMessageBuffer, strnlen_s(szSendMessageBuffer, sizeof(szSendMessageBuffer)), &pThreadInfo->sPublishMQ.bMQConnection, &pThreadInfo->sPublishMQ.bMQChannelOpen);
                WriteQueueLog(LogType_MQOut, LogLevel_Info, pThreadInfo->nThreadIndex, 'P', "", szReplyQueuename, szCorrelationID, nMessageLength, "%s", szMessageBuffer);
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Send Response Publish[Queue:%s,UUID:%s,Data:%s]!", pThreadInfo->nThreadIndex, szReplyQueuename, szCorrelationID, szMessageBuffer);
                continue;
            }
            nParsingOffset += sizeof(sReceiveMessageFrame.szRequestDateTime) - 1;
            nResult = GetCheckedValue(TYPE_ALPHA_NUMERIC, &sReceiveMessageFrame.szRespCode, sizeof(sReceiveMessageFrame.szRespCode) - 1, szMessageBuffer + nParsingOffset);
            if (nResult != STR_ERR_SUCCESS)
            {
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Receive Data Parsing Error-[RespCodeError:%-*.*s,Data:%s]!", pThreadInfo->nThreadIndex, sizeof(sizeof(sReceiveMessageFrame.szRespCode) - 1), sizeof(sizeof(sReceiveMessageFrame.szRespCode) - 1),  szMessageBuffer + nParsingOffset, szMessageBuffer);
                snprintf(szSendMessageBuffer, sizeof(szSendMessageBuffer), "%s%c%s%s%-8.8s%-14.14s%s%s", sReceiveMessageFrame.szOrganizationCode, sReceiveMessageFrame.cOccurType, sReceiveMessageFrame.szWorkType, sReceiveMessageFrame.szMsgType, sReceiveMessageFrame.szSerialNo, sReceiveMessageFrame.szRequestDateTime, GetSocketRespCode(RESP_FORMAT_ERROR), szMessageBuffer + MESSAGE_FRAME_SIZE);
                nResult = PutReplyMessageToQueue(pThreadInfo->sPublishMQ.sMQConnectionState, szCorrelationID, szReplyQueuename, szSendMessageBuffer, strnlen_s(szSendMessageBuffer, sizeof(szSendMessageBuffer)), &pThreadInfo->sPublishMQ.bMQConnection, &pThreadInfo->sPublishMQ.bMQChannelOpen);
                WriteQueueLog(LogType_MQOut, LogLevel_Info, pThreadInfo->nThreadIndex, 'P', "", szReplyQueuename, szCorrelationID, nMessageLength, "%s", szMessageBuffer);
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Send Response Publish[Queue:%s,UUID:%s,Data:%s]!", pThreadInfo->nThreadIndex, szReplyQueuename, szCorrelationID, szMessageBuffer);
                continue;
            }
            nParsingOffset += sizeof(sReceiveMessageFrame.szRespCode) - 1;
            SafeStrCopy(sReceiveMessageFrame.szData, sizeof(sReceiveMessageFrame.szData), szMessageBuffer + nParsingOffset);

            pCurlContext = curl_easy_init();
            if (g_bBypassMode)
            {
	            amqp_basic_ack(pThreadInfo->sConsumeMQ.sMQConnectionState, 1, nDeliveryTag, 0);
            }
            snprintf(szMessageID, sizeof(szMessageID), "%s%s", sReceiveMessageFrame.szWorkType, sReceiveMessageFrame.szMsgType);

            MessageProcessFunction = FindProcessFunction(szMessageID);
            nResult = MessageProcessFunction(pThreadInfo->nThreadIndex, pCurlContext, sReceiveMessageFrame.szData, strnlen(sReceiveMessageFrame.szData, sizeof(sReceiveMessageFrame.szData)), szRespDataBuffer, sizeof(szRespDataBuffer), szRespCode);
            printf("Http Result : %s\n", szRespDataBuffer);
            curl_easy_cleanup(pCurlContext);

            if (g_bBypassMode)
            {
                snprintf(szSendMessageBuffer, sizeof(szSendMessageBuffer), "%s%c%s%s%-8.8s%-14.14s%s%s", sReceiveMessageFrame.szOrganizationCode, sReceiveMessageFrame.cOccurType, sReceiveMessageFrame.szWorkType, sReceiveMessageFrame.szMsgType, sReceiveMessageFrame.szSerialNo, sReceiveMessageFrame.szRequestDateTime, GetSocketRespCode(RESP_FORMAT_ERROR), szRespDataBuffer);
                nResult = PutReplyMessageToQueue(pThreadInfo->sPublishMQ.sMQConnectionState, szCorrelationID, szReplyQueuename, szSendMessageBuffer, strnlen_s(szSendMessageBuffer, sizeof(szSendMessageBuffer)), &pThreadInfo->sPublishMQ.bMQConnection, &pThreadInfo->sPublishMQ.bMQChannelOpen);
                WriteQueueLog(LogType_MQOut, LogLevel_Info, pThreadInfo->nThreadIndex, 'P', "", szReplyQueuename, szCorrelationID, nMessageLength, "%s", szSendMessageBuffer);
                WriteLog(LogType_StandardOut, LogLevel_Info, "[Thread:%02d]Response Publish[Queue:%s,UUID:%s,Data:%s]!", pThreadInfo->nThreadIndex, szReplyQueuename, szCorrelationID, szSendMessageBuffer);
            }
            else
            {
                // 오류 판단 로직은 DB 처리 등의 결과에 의존하여 결정 되며 처리되기 전에는 메시지큐에 ack하지 않아야 데이터가 유지된다.
//                if (/* 오류 판단*/)
//                {
//                    amqp_basic_ack(pThreadInfo->sConsumeMQ.sMQConnectionState, 1, nDeliveryTag, 0);
//                }
//                else
//                {
//                    amqp_basic_nack(pThreadInfo->sConsumeMQ.sMQConnectionState, 1, nDeliveryTag, 0, 1);
//                }
#if 1
                nResult = SafeStrCmp(szRespCode, sizeof(szRespCode), GetSocketRespCode(RESP_NORMAL), &nCmpResult1);
                nResult = SafeStrCmp(szRespCode, sizeof(szRespCode), GetSocketRespCode(RESP_ALREADY_RECV), &nCmpResult2);
                if (nCmpResult1 != 0 && nCmpResult2 != 0)
                {
                    amqp_basic_nack(pThreadInfo->sConsumeMQ.sMQConnectionState, 1, nDeliveryTag, 0, 1);
                }
                else
                {
                    amqp_basic_ack(pThreadInfo->sConsumeMQ.sMQConnectionState, 1, nDeliveryTag, 0);
                }
#else
				amqp_basic_ack(pThreadInfo->sConsumeMQ.sMQConnectionState, 1, nDeliveryTag, 0);
#endif
            }
        }
        else
        {
            WriteLog(LogType_StandardOut, LogLevel_Debug, "[Thread:%02d]MQ Data Consume Error!", pThreadInfo->nThreadIndex);
        }
    }
    curl_global_cleanup();
    CloseMQ(pThreadInfo->nThreadIndex, pThreadInfo->sPublishMQ.sMQConnectionState, &pThreadInfo->sPublishMQ.bMQConnection, &pThreadInfo->sPublishMQ.bMQChannelOpen, &pThreadInfo->sPublishMQ.sMQMutex);
    CloseMQ(pThreadInfo->nThreadIndex, pThreadInfo->sConsumeMQ.sMQConnectionState, &pThreadInfo->sConsumeMQ.bMQConnection, &pThreadInfo->sConsumeMQ.bMQChannelOpen, &pThreadInfo->sConsumeMQ.sMQMutex);
    return pnThreadExitCode;
}

