#include    "goahead.h"
#include    "libipmi_IPM.h"
#include    "com_IPMIDefs.h"
#include    "ResultUtils.h"
#include    "cJSON.h"
#include    "libipmi_storlead_OEM.h"
#include    "libsensor.h"
#include    <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include "sel.h"
#include "libipmi_StorDevice.h"

void Web_ClearSEL(Webs *wp)
{
    int wRet = 0;

    IPMI20_UDS_SESSION_T    UDSSession;
    uint8_t target_addr;

    //Create session
    LIBIPMI_CreateSession(&UDSSession, DEFAULT_TIMEOUT);

    wp->index = TEST_INDEX;
    target_addr = gIPMBAddr[wp->index];
    if(target_addr == 0x20)
    {
        //get firmware version
        wRet = IPMICMD_ClearSEL( &UDSSession, DEFAULT_TIMEOUT);
    }
    else
    {
        wRet = IPMC_ClearSEL( &UDSSession, target_addr, DEFAULT_TIMEOUT);
    }

    if(wRet != 0)
        printf("Error trying to clear SEL!! %x\n", wRet);
    //Close session
    LIBIPMI_CloseSession(&UDSSession );


    char *pStr;
    cJSON * root =  cJSON_CreateObject();
    cJSON * data =  cJSON_CreateObject();
    cJSON_AddItemToObject(root, "data", data);//根节点下添加
    cJSON_AddStringToObject(root, "msg", "");
    cJSON_AddNumberToObject(root, "code", 200);

    if(wRet != 0)
        cJSON_AddStringToObject(data, "status", "fail");
    else
        cJSON_AddStringToObject(data, "status", "success");

    pStr = cJSON_PrintUnformatted(root);

//    printf("---> cJSON Str:\n%s\n", pStr);
    websSetStatus(wp, 200);
    websWriteHeaders(wp, -1, 0);
    websWriteEndHeaders(wp);
    websWrite(wp, "%s", pStr);
    websFlush(wp, 0);
    websDone(wp);

    if(pStr)
        wfree(pStr);
    if(root)
        cJSON_Delete(root);
}

void GetAllSELEntriesSorted(Webs *wp)
{
    int wRet = 0;
    unsigned short nEntries = 0;
    SELEventRecordWithSensorName_T *pSELBuff = NULL;
    //uint8 *pStartBuff = NULL;
    uint16 nMaxEntries = 0;
    IPMI20_UDS_SESSION_T    UDSSession;
    uint8_t target_addr;
    

    char *pStr;
    int code = 200;
    cJSON * root =  cJSON_CreateObject();
    cJSON  *pJsonArry,*pJsonsub;
    pJsonArry=cJSON_CreateArray();   /*创建数组*/

    //Create session
    LIBIPMI_CreateSession(&UDSSession, DEFAULT_TIMEOUT);

    wp->index = TEST_INDEX;
    target_addr = gIPMBAddr[wp->index];
    if(target_addr == 0x20)
    {
        /* Get number of SEL records in the system at this time */
        wRet = LIBIPMI_HL_GetNumOfSELEntries(&UDSSession, &nEntries, DEFAULT_TIMEOUT);
    }
    else
    {
        wRet = IPMC_GetNumOfSELEntries(&UDSSession, target_addr, &nEntries, DEFAULT_TIMEOUT);
    }

    if(wRet != 0)
    {
        printf("Error getting num of sel recods\n");
        goto error_out;
    }
    else
    {
        printf("success getting num of sel recods: %d\n",nEntries);
        /* Now get all sel records */
        //now find maximum possible sel entries and allocate that much
        if(target_addr == 0x20)
        {
              wRet = LIBIPMI_HL_GetMaxPossibleSELEntries(&UDSSession,&nMaxEntries,DEFAULT_TIMEOUT);
        }
        else
        {
            wRet = IPMC_GetMaxPossibleSELEntries(&UDSSession, target_addr, &nMaxEntries,DEFAULT_TIMEOUT);
        }

        if(wRet != 0)
        {
            printf("Error getting maximum no of entries..assuming 1024\n");
            nMaxEntries = 1024;
        }
        else
        {
            printf("MAX Possible SEL entries : %d\n",nMaxEntries);
        }

        /* Allocate the buffer to hold SEL entries */
        pSELBuff = (SELEventRecordWithSensorName_T *) walloc(nMaxEntries * sizeof(SELEventRecordWithSensorName_T));
        if(pSELBuff == NULL)
        {
            goto error_out;
        }
        //pStartBuff = (uint8 *)pSELBuff;

        printf("before get all sel entried\n");
        /* Now pass this buffer pointer to the function to get all SEL entries */
        wRet = Storlead_GetAllSelEntriesWithSensorNames(&UDSSession, target_addr, pSELBuff, DEFAULT_TIMEOUT);
        if(wRet == 0)
        {
            /* Write entries here */
            while(nEntries)
            {
                if(pSELBuff[nEntries-1].EventRecord.Valid != 0xA5)
                {
                    cJSON_AddItemToArray(pJsonArry,pJsonsub=cJSON_CreateObject()); /* 给创建的数组增加对对象*/
                    cJSON_AddNumberToObject(pJsonsub, "RecordID", pSELBuff[nEntries-1].EventRecord.EvtRecord.hdr.ID);
                    cJSON_AddNumberToObject(pJsonsub, "RecordType", pSELBuff[nEntries-1].EventRecord.EvtRecord.hdr.Type);
                    cJSON_AddNumberToObject(pJsonsub, "TimeStamp", pSELBuff[nEntries-1].EventRecord.EvtRecord.hdr.TimeStamp);
                    cJSON_AddNumberToObject(pJsonsub, "GenID1", pSELBuff[nEntries-1].EventRecord.EvtRecord.GenID[0]);
                    cJSON_AddNumberToObject(pJsonsub, "GenID2", pSELBuff[nEntries-1].EventRecord.EvtRecord.GenID[1]);
                    cJSON_AddNumberToObject(pJsonsub, "EvmRev", pSELBuff[nEntries-1].EventRecord.EvtRecord.EvMRev);
                    cJSON_AddNumberToObject(pJsonsub, "SensorType", pSELBuff[nEntries-1].EventRecord.EvtRecord.SensorType);
                    cJSON_AddStringToObject(pJsonsub, "SensorName", pSELBuff[nEntries-1].SensorName);
                    cJSON_AddNumberToObject(pJsonsub, "EventDirType", pSELBuff[nEntries-1].EventRecord.EvtRecord.EvtDirType);
                    cJSON_AddNumberToObject(pJsonsub, "EventData1", pSELBuff[nEntries-1].EventRecord.EvtRecord.EvtData1);
                    cJSON_AddNumberToObject(pJsonsub, "EventData2", pSELBuff[nEntries-1].EventRecord.EvtRecord.EvtData2);
                    cJSON_AddNumberToObject(pJsonsub, "EventData3", pSELBuff[nEntries-1].EventRecord.EvtRecord.EvtData3);                           
                }
                nEntries--;
            }

            cJSON_AddItemToObject(root, "data", pJsonArry);
            pStr = cJSON_PrintUnformatted(root);
            //printf("---> pStr %d: %s\n", strlen(pStr), pStr);

            websSetStatus(wp, 200);
            websWriteHeaders(wp, -1, 0);
            websWriteEndHeaders(wp); 
            websWrite(wp, pStr);
            websDone(wp);

            
        } else {
            printf("Error reading All SEL entries\n");
        }       
    }

    //Close session
    LIBIPMI_CloseSession(&UDSSession );
    
    if(root)
        cJSON_Delete(root);
    if(pStr)
        wfree(pStr);
    if(pSELBuff)
        wfree(pSELBuff);

    return;

error_out:
    //Close session
    LIBIPMI_CloseSession(&UDSSession );
    websError(wp, 404, "Get SEL error!");
    if(root)
        cJSON_Delete(root);
    if(pStr)
        wfree(pStr);
    if(pSELBuff)
        wfree(pSELBuff);

}


void SetTime(Webs *wp)
{
    int wRet = 0;
    IPMI20_UDS_SESSION_T    UDSSession;
    SetSELTimeReq_T SetSELTimeReq;
    SetSELTimeUTCOffsetReq_T SetSELTimeUTCOffsetReq;
    uint8_t target_addr;
    
    char *strUTCOffset = websGetVar(wp, "UTCOffset", NULL); //这里的时区单位是 分钟
    char *strTime = websGetVar(wp, "time", NULL);

    SetSELTimeUTCOffsetReq.UTCOffset = atoi(strUTCOffset);  //东8区就是 8*60
    printf("strUTCOffset: %s, UTCOffset: %d\n", strUTCOffset, SetSELTimeUTCOffsetReq.UTCOffset);
    
    SetSELTimeReq.Time = atoi(strTime);
    printf("strTime: %s, Time: %d\n", strTime, SetSELTimeReq.Time);
  
    //Create session
    LIBIPMI_CreateSession(&UDSSession, DEFAULT_TIMEOUT);
    
    wp->index = TEST_INDEX;
    target_addr = gIPMBAddr[wp->index];
    if(target_addr == 0x20)
    {
        wRet = IPMICMD_SetSELTime(&UDSSession,  &SetSELTimeReq, DEFAULT_TIMEOUT);
    }
    else
    {

    }
    if(wRet != 0)
    {
        websError(wp, 404, "Set sel time fail!");
        //Close session
        LIBIPMI_CloseSession(&UDSSession );
        return;
    }
    wp->index = TEST_INDEX;
    target_addr = gIPMBAddr[wp->index];
    if(target_addr == 0x20)
    {
        wRet = IPMICMD_SetSELTimeUTCOffset(&UDSSession, &SetSELTimeUTCOffsetReq, DEFAULT_TIMEOUT);
    }
    else
    {
        
    }
    if(wRet != 0)
    {
        websError(wp, 404, "Set sel time UTC offset fail!");
        //Close session
        LIBIPMI_CloseSession(&UDSSession );
        return;
    }
    //Close session
    LIBIPMI_CloseSession(&UDSSession );
    
    char *pStr;
    cJSON * root =  cJSON_CreateObject();
    cJSON * data =  cJSON_CreateObject();
    cJSON_AddItemToObject(root, "data", data);//根节点下添加
    cJSON_AddStringToObject(root, "msg", "");
    cJSON_AddNumberToObject(root, "code", 200);

  
    pStr = cJSON_PrintUnformatted(root);

//    printf("---> cJSON Str:\n%s\n", pStr);
    websSetStatus(wp, 200);
    websWriteHeaders(wp, -1, 0);
    websWriteEndHeaders(wp); 
    websWrite(wp,"%s", pStr);
    websFlush(wp, 0);
    websDone(wp);

    if(pStr)
        wfree(pStr);
    if(root)
        cJSON_Delete(root);

}


void GetTime(Webs *wp)
{
    int wRet = 0;
    IPMI20_UDS_SESSION_T    UDSSession;
    GetSELTimeRes_T GetSELTimeRes;
    GetSELTimeUTCOffsetRes_T GetSELTimeUTCOffsetRes;
  
    //Create session
    LIBIPMI_CreateSession(&UDSSession, DEFAULT_TIMEOUT);
    wRet = IPMICMD_GetSELTime(&UDSSession, &GetSELTimeRes, DEFAULT_TIMEOUT);
    if(wRet != 0)
    {
        websError(wp, 404, "Get sel time fail!");
        //Close session
        LIBIPMI_CloseSession(&UDSSession );
        return;
    }
    wRet = IPMICMD_GetSELTimeUTCOffset(&UDSSession, &GetSELTimeUTCOffsetRes, DEFAULT_TIMEOUT);
    if(wRet != 0)
    {
        websError(wp, 404, "Get time UTC offset fail!");
        //Close session
        LIBIPMI_CloseSession(&UDSSession );
        return;
    }
    //Close session
    LIBIPMI_CloseSession(&UDSSession );
    
    char *pStr;
    cJSON * root =  cJSON_CreateObject();
    cJSON * data =  cJSON_CreateObject();
    cJSON_AddItemToObject(root, "data", data);//根节点下添加
    cJSON_AddStringToObject(root, "msg", "");
    cJSON_AddNumberToObject(root, "code", 200);

    cJSON_AddNumberToObject(data, "time", GetSELTimeRes.Time);  //据1970年的秒数，UTC时间
    cJSON_AddNumberToObject(data, "UTCOffset", GetSELTimeUTCOffsetRes.UTCOffset);   //时区

  
    pStr = cJSON_PrintUnformatted(root);

    websSetStatus(wp, 200);
    websWriteHeaders(wp, -1, 0);
    websWriteEndHeaders(wp); 
    websWrite(wp,"%s", pStr);
    websFlush(wp, 0);
    websDone(wp);
    printf("---> cJSON Str:\n%s\n", pStr);

    if(pStr)
        wfree(pStr);
    if(root)
        cJSON_Delete(root);
}
