#ifndef __CAM_SYNC_MSG_QUE_HPP__
#define __CAM_SYNC_MSG_QUE_HPP__

#include <errno.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>

#include "X_Define_Internal.h"
#include "common_utils.hpp"

static int nMsgQue = 0;
static int msgQueId[MAX_CAM_COUNT]   = {-1 };
static int msgQueStat[MAX_CAM_COUNT] = { 0 };

static int initCamSyncMsgQueByCamId(const int CamId)
{
    // 相机ID检查
    if (CamId < 0 || CamId >= MAX_CAM_COUNT)
    {
        fprintf(stdout, "error in initCamSyncMsgQueByCamId, invalid CamId = %d\n", CamId);
        return 0;
    }
    
    msgQueId[CamId] = msgget((key_t)CAM_SYNC_MSG_QUE_KRY[CamId], 0600 | IPC_CREAT);
    if(msgQueId[CamId] == -1)
    {  
        fprintf(stderr, "initCamSyncMsgQueByCamId msgget failed with error: %d, msgQueKey = %d\n", errno, CAM_SYNC_MSG_QUE_KRY[CamId]);  
        return 0;
    }
    
    printf(" initCamSyncMsgQueByCamId msgget success, CamId = %d, msgQueKey = %d, msgQueId = %d\n", CamId, CAM_SYNC_MSG_QUE_KRY[CamId], msgQueId[CamId]);
    return 1;
}

static int initCamSyncMsgQueAll(const int Number)
{
    int     flag = 1;
    
    // 检查相机数量
    if (Number < 1 || Number > MAX_CAM_COUNT)
    {
        fprintf(stdout, "error in initAllCamSyncMsgQue, invalid Number = %d\n", Number);
        return 0;
    }
    
    nMsgQue = Number;
    for (int i = 0; i < Number; i++)
        flag = flag & initCamSyncMsgQueByCamId(i);
        
    return flag;
}

static int sendCamSyncMsgQueById(const int CamId, CAM_SYNC_MSG msg)
{
    CAM_SYNC_MSG_QUE queMsg;
    
    // 相机ID检查
    if (CamId < 0 || CamId >= MAX_CAM_COUNT)
    {
        fprintf(stdout, "error in sendCamSyncMsgQueById, invalid CamId = %d\n", CamId);
        return 0;
    }
    
    // 参数检查
    if (msg.systime == 0.0 || msg.gpstime == 0.0)
        return 0;
        
    // 检查队列初始化
    if(msgQueId[CamId] < 0)
        return 0;
    
    // 复制消息
    memcpy(&queMsg.msg, &msg, sizeof(CAM_SYNC_MSG));
    queMsg.msg_type = CAM_SYNC_MSG_QUE_KRY[CamId]; // 很关键！！
    if(msgsnd(msgQueId[CamId], (void*)&queMsg, sizeof(CAM_SYNC_MSG), IPC_NOWAIT) == -1)
    {
        if (EAGAIN == errno)
        {
            //printf(" msgsnd falied, buffer is overflow, msgQueId = %d\n", msgQueId[CamId]);
        }
        else
        {     
            fprintf(stdout, "msgsnd failed with error: %d, msgQueId = %d\n", errno, msgQueId[CamId]);  
        }
        
        return 0;
    }
        
    //printf(" msgsnd success, msgQueId = %d\n", msgQueId[CamId]);
    return 1;
}

static int sendCamSyncMsgQueAll(CAM_SYNC_MSG msg)
{
    int     flag = 1;
    
    // 参数检查
    if (msg.systime == 0.0 || msg.gpstime == 0.0)
        return 0;
    
    // 遍历消息队列发送
    for (int i = 0; i < nMsgQue; i++)
    {
        flag = flag & sendCamSyncMsgQueById(i, msg);
    }
    
    return flag;
}

static int rcvCamSyncMsgQue(const int CamId, CAM_SYNC_MSG *msg)
{
    CAM_SYNC_MSG_QUE    queMsg;
    
    // 相机ID检查
    if (CamId < 0 || CamId >= MAX_CAM_COUNT)
    {
        fprintf(stdout, "error in rcvCamSyncMsgQue, invalid CamId = %d\n", CamId);
        return 0;
    }
    
    // 检查消息队列初始化
    if (msgQueId[CamId] < 0)
    {
        fprintf(stdout, "error in rcvCamSyncMsgQue, invalid msgQueId = %d\n", msgQueId[CamId]);
        return 0;          
    }
    
    if(msgrcv(msgQueId[CamId], (void*)&queMsg, sizeof(CAM_SYNC_MSG), CAM_SYNC_MSG_QUE_KRY[CamId], 0) == -1)
    {
        fprintf(stderr, "msgrcv failed with errno: %d，msgQueId = %d\n", errno, msgQueId[CamId]);  
        return 0;
    }
    
    // 复制消息
    if (msg != NULL)
        memcpy(msg, &queMsg.msg, sizeof(CAM_SYNC_MSG));
    else
        printf("rcvCamSyncMsgQue %.6lf %09ld %.6lf %.6lf\n", timeget_gpssec(), queMsg.msg.seq, queMsg.msg.systime, queMsg.msg.gpstime);
    
    return 1;
}

#endif // __CAM_SYNC_MSG_QUE_HPP__

