//---------------------------------------------------------------------------


#pragma hdrstop

#include "FrmMainCommF.h"
#include "AppGlobalF.h"
#include "FrmMainF.h"
#include "DMCOMMF.h"
#include "CommThread.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

void __fastcall TFrmMain::SendInitial(void)
{
    int result;

LINFO("SendInitial");
    if ((result = SendProcessState()) != VERR_NONE)
    {
        LERROR("SendProcessState failed %d", result);
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmMain::SendTerminal(void)
{
    int result;

LINFO("SendTerminal");
    // 동작, 통신, DB 모두 이상 처리
    m_bAction = state_error;
    m_bComm   = state_error;
    m_bDB     = state_error;

    // 모든 시설물 통신 오프라인 처리
    VmsIterator it;
    for(it=VmsManager->FLists.FMapObject.begin(); it != VmsManager->FLists.FMapObject.end(); ++it)
    {
        TVmsCtlr *pObj = (TVmsCtlr*)it->second;
        if (pObj->Server.UseFlag != bit_enable) continue;

        pObj->Server.Status = process_fail;
        pObj->ChangeDate    = Now().FormatString("yyyymmddhhnnss");
    }

    SendProcessState();

    // DB에 상태정보를 업데이트 하구...
    if (DMCOMM->DbConnect(g_AppCfg.db.sConnectStr))
    {
        if ((result = DMCOMM->SaveProcessStateProc()) != VERR_NONE)
        {
            LERROR("SaveProcessStateProc Error %d", result);
        }
        if ((result = DMCOMM->SaveEquipStateAllProc()) != VERR_NONE)
        {
            LERROR("SaveEquipStateAllProc Error %d", result);
        }
        DMCOMM->DbClose();
    }
}
//---------------------------------------------------------------------------

int __fastcall TFrmMain::SendProcessState()
{
    int result;
    INT_PG_STATE_RES PgState;

    memset(&PgState, 0x00, sizeof(PgState));

    g_SysInfo->State.Action = m_bAction;
    g_SysInfo->State.Comm   = m_bComm;
    g_SysInfo->State.DB     = m_bDB;

    PgState.Count = 1;
    PgState.Unit[0].Type    = INT_ID_VMS_SERVER;
    PgState.Unit[0].DB      = m_bDB;
    PgState.Unit[0].Comm    = m_bComm;
    PgState.Unit[0].Action  = m_bAction;

    if (FServerRun == false)
    {
        PgState.Unit[0].Action = state_error;
        g_SysInfo->State.Action = state_error;
    }
    result = VComm_CmmProcessStateNotify(&PgState);

    if (m_bAction != state_error)   //프로세스 종료처리중이 아닌경우
    {
        result = SendDbThreadMessage(WM_PROCESS_STATE, NULL, NULL);
        if (result != SYS_ERR_NONE)
        {
            LERROR("SendDbThreadMessage Error %d", result);
        }
        LINFO(">>>>>>>>>>>>>>> SendProcessState: %d,%d,%d", PgState.Unit[0].Action, PgState.Unit[0].Comm, PgState.Unit[0].DB);
    }

    return result;
}
//---------------------------------------------------------------------------

void __fastcall TFrmMain::CheckCommState()
{
    int i;
    int uCount, rCount;
    bool eFlag;

    FSendMsg = SEND_MSG_NONE;

    if (VmsManager->Total == VmsManager->Normal) m_bComm = state_normal;
    else                                         m_bComm = state_error;

    /* 통신 데이터 처리 스레드 체크 */
    int Flag;
    DWORD ExitCode;

    if ((m_CommThreadID != NULL) && (m_CommHandle != NULL))
    {
        if (GetExitCodeThread((HANDLE)m_CommHandle, &ExitCode))
        {
            if (STILL_ACTIVE == ExitCode) Flag = 0;
            else                          Flag = -1;
        }
        else Flag = -2;
    }
    else Flag = -3;

    if (Flag)
    {
        m_bAction = state_error;

        String sError = SYS_GetSysError();
        LERROR("DB Server abnormal terminated, try restart: %d (%s)", Flag, AnsiString(sError).c_str());
        //AutoClose();
        StartJobThread();
    }
    else
    {
        //if (tbConnect->Enabled == false)
        {
            m_bAction = state_normal;
        }
    }
    if (g_SysInfo->State.Action != m_bAction ||
        g_SysInfo->State.Comm   != m_bComm   ||
        g_SysInfo->State.DB     != m_bDB      )
    {
        //SendProcessState();
        FSendMsg += SEND_MSG_PROCESS;
    }
}
//---------------------------------------------------------------------------

int __fastcall TFrmMain::SendVmsThreadMessage(BYTE *AVmsId, IPCUDPMESSAGESTRUCT *ARcvData, BYTE AOpCode, char *AData)
{
    AnsiString    sVmsId;
    IPCUDPPACKET *pPI = NULL;

    sVmsId.sprintf("%.*s", INT_VMS_MAX_ID, (char*)AVmsId);

    TVmsCtlr *pObj = VmsManager->FLists.Find(sVmsId);
    if (!pObj)
    {
        return VERR_NOTFOUND_VMS;
    }

    if (pObj->Server.Status != process_run)
    {
        return VERR_OFFLINE;
    }

    if (!pObj->pPackQueue)
    {
        return VERR_INTERNAL;
    }

    pPI = new IPCUDPPACKET;
    if (pPI == NULL) return VERR_MEMORY_ALLOC;

    pPI->Sender.IP   = ARcvData->Sender.IP;
    pPI->Sender.Port = ARcvData->Sender.Port;
    pPI->RecvId      = ARcvData->Pkt.head.SendId;
    pPI->OPCode      = AOpCode;
    pPI->Size        = (int)ARcvData->Pkt.head.Length;
    if (pPI->Size > 0)
    {
        pPI->Data = new char[pPI->Size];
        if (!pPI->Data)
        {
            delete pPI;
            return VERR_INTERNAL;
        }
        CopyMemory(pPI->Data, AData, pPI->Size);
    }
    pObj->pPackQueue->Add((void*)pPI);
    return VERR_NONE;
}
//---------------------------------------------------------------------------

