/* Finalize function for Event */
ClRcT corEventFinalize(void)
{

 /* Close all the event channels */
  clEventChannelClose(corEventChannelHandle);
  clEventChannelClose(cpmEventChannelHandle);
  clEventChannelClose(cpmEventNodeChannelHandle);

  return (clEventFinalize(corEventHandle));
}
static ClRcT clMsgEventFinalize(void)
{
    ClRcT rc;

    rc = clEventChannelClose(gCpmChHdl);
    if(rc != CL_OK)
        clLogError("EVT", "FIN", "Failed to close CPM event channel. error code [0x%x]", rc);

    rc = clEventFinalize(gMsgEvtHdl);
    if(rc != CL_OK)
        clLogError("EVT", "FIN", "Failed to finalize event library. error code [0x%x].", rc);

    return rc;
}
static ClRcT clMsgEventInitialize(void)
{
    ClRcT rc, retCode;
    ClVersionT version = CL_EVENT_VERSION;
    ClEventCallbacksT msgEvtCallbacks = { NULL, clMsgEventCallbackFunc };

    ClNameT cpmEvtCh = {0};
    ClEventChannelOpenFlagsT cpmChOpenFlags = CL_EVENT_CHANNEL_SUBSCRIBER | CL_EVENT_GLOBAL_CHANNEL;

    ClUint32T nodeDepPattern = htonl(CL_CPM_NODE_DEPART_PATTERN);
    ClEventFilterT nodeDepFilter[] = {{CL_EVENT_EXACT_FILTER, {0, (ClSizeT)sizeof(nodeDepPattern), (ClUint8T*)&nodeDepPattern}}};
    ClEventFilterArrayT nodeDepFltArray = {sizeof(nodeDepFilter)/sizeof(nodeDepFilter[0]), nodeDepFilter};

    rc = clEventInitialize(&gMsgEvtHdl, &msgEvtCallbacks, &version);
    if(rc != CL_OK)
    {
        clLogError("EVT", "INI", "Failed to initialize the event client. error code [0x%x].", rc);
        goto error_out;
    }

    clNameSet(&cpmEvtCh, CL_CPM_NODE_EVENT_CHANNEL_NAME);

    rc = clEventChannelOpen(gMsgEvtHdl, &cpmEvtCh, cpmChOpenFlags, SA_TIME_MAX, &gCpmChHdl);
    if(rc != CL_OK)
    {
        clLogError("EVT", "INI", "Failed to open event channel. error code [0x%x].", rc);
        goto error_out_1;
    }

    rc = clEventSubscribe(gCpmChHdl, &nodeDepFltArray, 0, NULL);
    if(rc != CL_OK)
    {
        clLogError("EVT", "INI", "Failed to subscribe for node departure event. error code [0x%x].", rc);
        goto error_out_2;
    }

    goto out;

error_out_2:
    retCode = clEventChannelClose(gCpmChHdl);
    if(retCode != CL_OK)
        clLogError("EVT", "INI", "Failed to close CPM event channel. error code [0x%x].", retCode);
error_out_1:
    retCode = clEventFinalize(gMsgEvtHdl);
    if(retCode != CL_OK)
        clLogError("EVT", "INI", "Failed to finalize event library. error code [0x%x].", retCode);
error_out:
out:
    return rc;
}
static ClRcT clSubsEventLibrayInitialize(void)
{
    ClRcT rc = CL_OK;

    ClVersionT version = CL_EVENT_VERSION;    
    ClNameT channelName = {sizeof(CL_EO_EVENT_CHANNEL_NAME)-1, CL_EO_EVENT_CHANNEL_NAME};

    const ClEventCallbacksT evtCallbacks = 
    {
        NULL, // clSubsAsyncChannelOpenCb for Async Channel Open
        clSubEoEventWaterMarkCb,  // Event Delivery Callback
    };
    ClEventChannelOpenFlagsT evtFlags = CL_EVENT_CHANNEL_SUBSCRIBER | CL_EVENT_LOCAL_CHANNEL;

    rc = clEventInitialize(&gSubsEventInfo.initHandle, &evtCallbacks, &version);
    if(CL_OK != rc)
    {
        clOsalPrintf("clEventInitialize() failed [%#X]\n",rc);
        goto failure;
    }

    rc = clEventChannelOpen(gSubsEventInfo.initHandle, &channelName, 
            evtFlags, CL_RMD_DEFAULT_TIMEOUT, 
            &gSubsEventInfo.channelHandle);
    if(CL_OK != rc)
    {
        clOsalPrintf("clEventChannelOpen() failed [%#X]\n",rc);
        goto init_done;
    }

    rc = clEventSubscribe(gSubsEventInfo.channelHandle, CL_EVENT_DEFAULT_SUBS_FILTER, UNIQUE_SUBSCRIPTION_ID, 
            "User Specified Argument (cookie) for the event delivery callback");
    if(CL_OK != rc)
    {
        clOsalPrintf("clEventSubscribe() failed [%#X]\n",rc);
        goto channel_opened;
    }

    return CL_OK;

channel_opened:
    clEventChannelClose(gSubsEventInfo.channelHandle);

init_done:
    clEventFinalize(gSubsEventInfo.initHandle);

failure:
    return rc;
}
static ClRcT clPubsEventLibrayFinalize(void)
{
    ClRcT rc = CL_OK;

    rc = clEventChannelClose(gPubsEventInfo.channelHandle);
    if(CL_OK != rc)
    {
        clOsalPrintf("clEventChannelClose() failed [%#X]\n",rc);
    }

    rc = clEventFinalize(gPubsEventInfo.initHandle);
    if(CL_OK != rc)
    {
        clOsalPrintf("clEventFinalize() failed [%#X]\n",rc);
    }

    return CL_OK;
}
static ClRcT clPubsEventLibrayInitialize(void)
{
    ClRcT rc = CL_OK;

    ClVersionT version = CL_EVENT_VERSION;    
    SaNameT channelName = {sizeof(CL_EO_EVENT_CHANNEL_NAME)-1, CL_EO_EVENT_CHANNEL_NAME};

    const ClEventCallbacksT evtCallbacks = 
    {
        clPubsAsyncChannelOpenCb, // Can be NULL if sync call is used
        NULL,   // Since it is not a subscriber  
    };
    ClEventChannelOpenFlagsT evtFlags = CL_EVENT_CHANNEL_PUBLISHER | CL_EVENT_LOCAL_CHANNEL;

    ClInvocationT invocation = UNIQUE_INVOCATION_ID; // To identify the callback

    rc = clEventInitialize(&gPubsEventInfo.initHandle, &evtCallbacks, &version);
    if(CL_OK != rc)
    {
        clOsalPrintf("clEventInitialize() failed [%#X]\n",rc);
        goto failure;
    }

    rc = clEventChannelOpenAsync(gPubsEventInfo.initHandle, invocation, 
            &channelName, evtFlags);
    if(CL_OK != rc)
    {
        clOsalPrintf("clEventChannelOpen() failed [%#X]\n",rc);
        goto init_done;
    }

    return CL_OK;

init_done:
    clEventFinalize(gPubsEventInfo.initHandle);

failure:
    return rc;
}
static ClRcT clSubsEventLibrayFinalize(void)
{
    ClRcT rc = CL_OK;

    rc = clEventUnsubscribe(gSubsEventInfo.channelHandle, UNIQUE_SUBSCRIPTION_ID);
    if(CL_OK != rc)
    {
        clOsalPrintf("clEventUnsubscribe() failed [%#X]\n",rc);
    }

    rc = clEventChannelClose(gSubsEventInfo.channelHandle);
    if(CL_OK != rc)
    {
        clOsalPrintf("clEventChannelClose() failed [%#X]\n",rc);
    }

    rc = clEventFinalize(gSubsEventInfo.initHandle);
    if(CL_OK != rc)
    {
        clOsalPrintf("clEventFinalize() failed [%#X]\n",rc);
    }

    return CL_OK;
}