/**
 *  Get Node Name given MoId.
 *
 *  API to get Logical NodeName given MOId. 
 *
 *
 *  @param pMoId      MOId of the Blade.
 *  @param nodeName   Node name corresponding to blade MOId
 *
 *  @returns 
 *    CL_OK on success <br/>
 *    CL_COR_SET_RC(CL_COR_ERR_NOT_EXIST) If an entry is not present for given MOId<br/>
 *    CL_COR_SET_RC(CL_COR_ERR_NULL_PTR) if moId is NULL <br/>
 */
ClRcT _clCorMoIdToNodeNameGet(ClCorMOIdPtrT pMoId, ClNameT** nodeName)
{
    ClRcT rc;
    ClUint16T OriginalDepth;
    ClCorMOServiceIdT  svcId;
    ClCorMOClassPathT moclassPath;
    CORMOClass_h moClassH;

	if(pMoId == NULL)
		return CL_COR_SET_RC(CL_COR_ERR_NULL_PTR);

    /* First check if the MOId passed by the user is valid or not*/

    /* The minimum condition that must be satisfied is */
    /* taht the MO class should exist*/
    rc = clCorMoIdToMoClassPathGet(pMoId, &moclassPath);

    if(CL_OK != rc)
    	CL_COR_RETURN_ERROR(CL_DEBUG_ERROR, "\nCould not get MO class path from MOID", rc);

    /* Check if the MO class exists or not */
    rc = corMOClassHandleGet(&moclassPath, &moClassH);
    
    if (rc != CL_OK)
    	{
    	/* The mo class does not exist. Return*/
    	CL_COR_RETURN_ERROR(CL_DEBUG_ERROR, "\nIncorrect path specified. MO class does not exist\n", rc);
    	}

    /* The user has passed MOId, Since we are going to work on MOId */
    /* Passed by the user, let's store the original depth and svc Id */

    OriginalDepth = pMoId->depth;
    svcId = pMoId->svcId;

    pMoId->svcId = CL_COR_INVALID_SVC_ID;

    for(; pMoId->depth>=1; pMoId->depth--)
    	{
    	/* Find if the MOId is present in the Hash Table */
    	rc = clCntDataForKeyGet(moIdToNodeNameTableHandle, (ClCntKeyHandleT) pMoId, (ClCntDataHandleT *) nodeName);
    	if(CL_OK == rc && *nodeName !=NULL )
    		{
    		/* Found the node name for given MOId. Return.*/
    		/* Before returning restore svc Id and depth */
    		pMoId->depth = OriginalDepth;
    		pMoId->svcId = svcId;
    		return CL_OK;
    		}
    	}

    /* If we are here then the node Name could not be found*/
    /* Restore original depth and svcId and return */

    pMoId->depth = OriginalDepth;
    pMoId->svcId = svcId;

    CL_COR_RETURN_ERROR(CL_DEBUG_TRACE, "\n Node Name not found for given MOId.\n", CL_COR_SET_RC(CL_COR_ERR_NOT_EXIST));

}
ClRcT VDECL(_CORNotifyGetAttrBits) (ClEoDataT cData, ClBufferHandleT  inMsgHandle,
                        ClBufferHandleT  outMsgHandle)
{
	ClRcT             rc = CL_OK;
	ClCorMOIdT        moId;
 	ClCorClassTypeT   classId;
	ClCorMOClassPathT moClsPath;
	ClUint32T         attrCnt;
    ClCorAttrPathT    attrPath;
	ClCorAttrListT   *pAttrList = NULL;
    ClCorAttrBitsT    attBits = {{0}};
	ClVersionT version;

    if(gCorInitStage == CL_COR_INIT_INCOMPLETE)
    {
        clLogError("NTF", "ATB", "The COR server Initialization is in progress....");
        return CL_COR_SET_RC(CL_COR_ERR_TRY_AGAIN);
    }

    /* Adding the version related check */
	if((rc = clXdrUnmarshallClVersionT(inMsgHandle, &version )) != CL_OK)
	     return (rc);
	/* Client to Server Version Check */
	clCorClientToServerVersionValidate(version, rc);
    if(rc != CL_OK)
	{
		return CL_COR_SET_RC(CL_COR_ERR_VERSION_UNSUPPORTED); 
	}

	if((rc = VDECL_VER(clXdrUnmarshallClCorMOIdT, 4, 0, 0)(inMsgHandle, &moId )) != CL_OK)
	     return (rc);

	 if((rc = VDECL_VER(clXdrUnmarshallClCorAttrPathT, 4, 0, 0)(inMsgHandle, &attrPath )) != CL_OK)
	     return (rc);
 
	 if((rc = clXdrUnmarshallClUint32T(inMsgHandle, &attrCnt )) != CL_OK)
	     return (rc);
	

        clCorMoIdToMoClassPathGet (&moId, &moClsPath);
        /* can not use wild card in moID when requesting specific attribute change */
	if ((moId.svcId == CL_COR_SVC_WILD_CARD) || (clCorDoesPathContainWildCard(&moClsPath)))
    	{
                 CL_DEBUG_PRINT (CL_DEBUG_ERROR, ( "Can not use wild cards for class type/svcId \
		                                      when using a list of attribute Ids\n"));
        	CL_FUNC_EXIT();
        	return (CL_COR_SET_RC(CL_COR_NOTIFY_ERR_CANNOT_RESOLVE_CLASS));
    	}
/**
 *  Convert class IDs into class idx within a ClCorMOId.
 *
 *  This routine walks through all the valid entries in a ClCorMOId and
 * converts class ids into corresponding class index. Class
 * index represents the index of the class in ClCorMOId tree node array.
 * Note that this conversion is done "in-place", i.e., input ClCorMOId is
 * changed to have idx instead of class ID.
 *
 *  @param moId  - ClCorMOId to convert.
 *
 *  @returns CL_OK  - Success<br>
 *           CL_COR_SET_RC(CL_COR_ERR_NULL_PTR) or CL_COR_SET_RC(CL_COR_ERR_INVALID_CLASS) on error.
 */
ClRcT 
corMOTreeClass2IdxConvert(ClCorMOIdPtrT moId)
{
    int i;
    ClRcT rc;
    ClCorMOClassPathT path;

    CL_FUNC_ENTER();
    
    if(!moTree)
      return (CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
    
    if (moId == NULL)
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "NULL argument"));
        CL_FUNC_EXIT();
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
      }
    /* convert moId to corPath */
    rc = clCorMoIdToMoClassPathGet(moId, &path);
    if(rc == CL_OK)
      {
        if((rc = mArrayId2Idx(moTree, (ClUint32T *)path.node, path.depth))!=CL_OK)
          {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "corMOTreeClassIdxGet failed rc => [0x%x]", rc));
          }
        else
          {
            /* copy the corPath indexes to ClCorMOId */
            for(i=0;(i<moId->depth) && (i < CL_COR_HANDLE_MAX_DEPTH);i++)
              {
                moId->node[i].type=path.node[i];
              }
          }
      }

    CL_FUNC_EXIT();
    return(rc);
}
/*
 * Create objects for the static AMF entities.
 */
ClRcT corAmfTreeInitialize(void)
{
    ClRcT rc = CL_OK;

    if(gClAmfMibLoaded)
    {
        rc = corAmfMibTreeInitialize();
    }
    else
    {
        ClVersionT version = {'B', 0x1 , 0x1};
        ClCorMOIdT moId;
        ClAmsEntityBufferT nodeList = {0};
        ClAmsEntityBufferT suList = {0};
        ClAmsEntityBufferT compList = {0};
        ClAmsEntityBufferT sgList = {0};
        ClAmsEntityBufferT siList = {0};
        ClAmsEntityBufferT csiList = {0};
        ClCorClassTypeT classIds[CL_AMS_ENTITY_TYPE_MAX+2] = {0};
        ClCorMOClassPathT sgClassPath;
        ClInt32T i;

        rc = corAmfEntityInitialize();
        if(rc != CL_OK) goto out;

        rc = clAmsMgmtInitialize(&mgmtHandle,  NULL, &version);
        if(rc != CL_OK)
        {
            clLogError("COR", "AMF", "Mgmt initialize returned [%#x]", rc);
            goto out;
        }

        if( (rc = clAmsMgmtGetNodeList(mgmtHandle, &nodeList)) != CL_OK)
        {
            clLogError("COR", "AMF", "Node list returned [%#x]", rc);
            goto out;
        }

        /*
         * Create object heirarchy for nodes/sus/comps. 
         */
        for(i = 0; i < nodeList.count; ++i)
        {
            ClInt32T j;
            ClCorMOClassPathT nodeClassPath;

            rc = clCorMoIdInitialize(&moId);
            CL_ASSERT(rc == CL_OK);

            rc = clCorNodeNameToMoIdGet(nodeList.entity[i].name, &moId);
            if(rc != CL_OK)
            {
                clLogError("COR", "AMF", "Node name to moid get for [%s] failed with [%#x]",
                           nodeList.entity[i].name.value, rc);
                goto out;
            }

            rc = clCorMoClassPathInitialize(&nodeClassPath);
            CL_ASSERT(rc == CL_OK);
        
            rc = clCorMoIdToMoClassPathGet(&moId, &nodeClassPath);
            CL_ASSERT(rc == CL_OK);

            /*
             * Now get nodes su list.
             */
            rc = clAmsMgmtGetNodeSUList(mgmtHandle, &nodeList.entity[i], &suList);
            if(rc != CL_OK)
            {
                clLogError("COR", "AMF", "Node [%s] su list returned [%#x]", 
                           nodeList.entity[i].name.value, rc);
                goto out;
            }

            if(!classIds[CL_AMS_ENTITY_TYPE_SU])
            {
                rc = corAmfEntityClassGet(CL_AMS_ENTITY_TYPE_SU, classIds+CL_AMS_ENTITY_TYPE_SU);
                if(rc != CL_OK)
                {
                    clLogError("COR", "AMF", "Class for entity SU not found");
                    goto out;
                }
            }
        
            if(!classIds[CL_AMS_ENTITY_TYPE_COMP])
            {
                rc = corAmfEntityClassGet(CL_AMS_ENTITY_TYPE_COMP, classIds+CL_AMS_ENTITY_TYPE_COMP);
                if(rc != CL_OK)
                {
                    clLogError("COR", "AMF", "Class for entity comp not found");
                    goto out;
                }
            }

            rc = clCorMoClassPathAppend(&nodeClassPath, classIds[CL_AMS_ENTITY_TYPE_SU]);
            CL_ASSERT(rc == CL_OK);

            rc = corAmfMoClassCreate("AMFSu", &nodeClassPath, NULL);
            if(rc != CL_OK)
            {
                if(CL_GET_ERROR_CODE(rc) != CL_COR_MO_TREE_ERR_FAILED_TO_ADD_NODE)
                    goto out;
            }

            if(CL_GET_ERROR_CODE(rc) != CL_COR_MO_TREE_ERR_FAILED_TO_ADD_NODE)
            {
                rc = clCorMoClassPathAppend(&nodeClassPath, classIds[CL_AMS_ENTITY_TYPE_COMP]);
                CL_ASSERT(rc == CL_OK);
            
                rc = corAmfMoClassCreate("AMFComp", &nodeClassPath, NULL);
                if(rc != CL_OK) goto out;
            }
            else
            {
                rc = CL_OK;
            }

            for(j = 0; j < suList.count; ++j)
            {
                ClInt32T k;
                ClCorMOIdT suMoId;

                memcpy(&suMoId, &moId, sizeof(suMoId));
                rc = clCorMoIdAppend(&suMoId, classIds[CL_AMS_ENTITY_TYPE_SU], j);
                CL_ASSERT(rc == CL_OK);

                rc = corAmfObjectCreate(0, &suList.entity[j], &suMoId);
                if(rc != CL_OK) goto out;

                rc = clAmsMgmtGetSUCompList(mgmtHandle, &suList.entity[j], &compList);
                if(rc != CL_OK)
                {
                    goto out;
                }
            
                for(k = 0; k < compList.count; ++k)
                {
                    ClCorMOIdT compMoId;
   
                    memcpy(&compMoId, &suMoId, sizeof(compMoId));
                    rc = clCorMoIdAppend(&compMoId, classIds[CL_AMS_ENTITY_TYPE_COMP], k);
                    CL_ASSERT(rc == CL_OK);

                    rc = corAmfObjectCreate(0, &compList.entity[k], &compMoId);
                    if(rc != CL_OK) goto out;
                }
                clHeapFree(compList.entity);
                compList.entity = NULL;
            }
            clHeapFree(suList.entity);
            suList.entity = NULL;
        }

        /*
         * Configure object heirarchy for SGs.
         */
        rc = clAmsMgmtGetSGList(mgmtHandle, &sgList);
        if(rc != CL_OK)
        {
            clLogError("COR", "AMF", "SG list returned [%#x]", rc);
            goto out;
        }

        rc = corAmfEntityClassGet(CL_AMS_ENTITY_TYPE_SG, &classIds[CL_AMS_ENTITY_TYPE_SG]);
        if(rc != CL_OK)
        {
            clLogError("COR", "AMF", "SG entity class not found");
            goto out;
        }

        rc = corAmfEntityClassGet(CL_AMS_ENTITY_TYPE_SG, &classIds[CL_AMS_ENTITY_TYPE_SI]);
        if(rc != CL_OK)
        {
            clLogError("COR", "AMF", "SI entity class not found");
            goto out;
        }

        rc = corAmfEntityClassGet(CL_AMS_ENTITY_TYPE_SG, &classIds[CL_AMS_ENTITY_TYPE_CSI]);
        if(rc != CL_OK)
        {
            clLogError("COR", "AMF", "CSI entity class not found");
            goto out;
        }

        rc = clCorMoClassPathInitialize(&sgClassPath);
        CL_ASSERT(rc == CL_OK);
        rc = clCorMoClassPathAppend(&sgClassPath, classIds[CL_AMS_ENTITY_TYPE_SG]);
        CL_ASSERT(rc == CL_OK);

        rc = corAmfMoClassCreate("AMFSg", &sgClassPath, NULL);
        if(rc != CL_OK) goto out;
       
        rc = clCorMoClassPathAppend(&sgClassPath, classIds[CL_AMS_ENTITY_TYPE_SI]);
        CL_ASSERT(rc == CL_OK);
            
        rc = corAmfMoClassCreate("AMFSi", &sgClassPath, NULL);
        if(rc != CL_OK) goto out;

        rc = clCorMoClassPathAppend(&sgClassPath, classIds[CL_AMS_ENTITY_TYPE_CSI]);
        CL_ASSERT(rc == CL_OK);

        rc = corAmfMoClassCreate("AMFCsi", &sgClassPath, NULL);
        if(rc != CL_OK) goto out;

        for(i = 0; i < sgList.count; ++i)
        {
            ClInt32T j;

            rc = clCorMoIdInitialize(&moId);
            CL_ASSERT(rc == CL_OK);
            rc = clCorMoIdAppend(&moId, classIds[CL_AMS_ENTITY_TYPE_SG], i);
            CL_ASSERT(rc == CL_OK);

            rc = corAmfObjectCreate(0, &sgList.entity[i], &moId);
            if(rc != CL_OK) goto out;

            rc = clAmsMgmtGetSGSIList(mgmtHandle, &sgList.entity[i], &siList);
            if(rc != CL_OK)
            {
                clLogError("COR", "AMF", "SI list get for SG [%s] returned [%#x]",
                           sgList.entity[i].name.value, rc);
                goto out;
            }
        
            for(j = 0; j < siList.count; ++j)
            {
                ClInt32T k;
                ClCorMOIdT siMoId;

                memcpy(&siMoId, &moId, sizeof(siMoId));
                rc = clCorMoIdAppend(&siMoId, classIds[CL_AMS_ENTITY_TYPE_SI], j);
                CL_ASSERT(rc == CL_OK);

                rc = corAmfObjectCreate(0, &siList.entity[j], &siMoId);
                if(rc != CL_OK) goto out;

                rc = clAmsMgmtGetSICSIList(mgmtHandle, &siList.entity[j], &csiList);
                if(rc != CL_OK)
                {
                    clLogError("COR", "AMF", "CSI list for SI [%s] returned [%#x]",
                               siList.entity[j].name.value, rc);
                    goto out;
                }

                for(k = 0; k < csiList.count; ++k)
                {
                    ClCorMOIdT csiMoId;
                    memcpy(&csiMoId, &siMoId, sizeof(csiMoId));
                    rc = clCorMoIdAppend(&csiMoId, classIds[CL_AMS_ENTITY_TYPE_CSI], k);
                    CL_ASSERT(rc == CL_OK);
                    rc = corAmfObjectCreate(0, &csiList.entity[k], &csiMoId);
                    if(rc != CL_OK) goto out;
                }
                clHeapFree(csiList.entity);
                csiList.entity = NULL;
            }
            clHeapFree(siList.entity);
            siList.entity = NULL;
        }

        /*
         * We are here when the objects are all created. Do a commit
         */
        rc = corAmfObjectCommit();
        if(rc != CL_OK)
        {
            clLogError("COR", "AMF", "Object commit returned [%#x]", rc);
            goto out;
        }

        clLogNotice("COR", "AMF", "COR AMF tree successfully initialized");

        out:
        if(nodeList.entity) 
            clHeapFree(nodeList.entity);
        if(suList.entity)   
            clHeapFree(suList.entity);
        if(compList.entity) 
            clHeapFree(compList.entity);
        if(sgList.entity)   
            clHeapFree(sgList.entity);
        if(siList.entity)   
            clHeapFree(siList.entity);
        if(csiList.entity) 
            clHeapFree(csiList.entity);
    }
    return rc;
}
ClRcT
clProvProvisionOmCreateAndRuleAdd( SaNameT* pResourceStringMoId,
                                   ClCorMOIdPtrT pFullMoId,
                                   ClCorAddrT* pProvAddr,
                                   ClUint32T createFlag,
                                   ClBoolT   autoCreateFlag,
                                   ClUint32T primaryOIFlag,
                                   ClUint32T wildCardFlag )
{
    ClRcT               rc          = CL_OK;
    ClCorMOClassPathT   moPath;

    CL_FUNC_ENTER();

    rc = clCorMoIdNameToMoIdGet( pResourceStringMoId, pFullMoId );
    CL_PROV_CHECK_RC1_LOG1( rc, CL_OK, CL_PROV_RC(CL_PROV_INTERNAL_ERROR), CL_LOG_ERROR,
                            CL_PROV_LOG_1_MOID_STRING_MOID, rc );

    /*
     * If given Prov MSO is not associated for given resource then don't add the rule 
     * silently supperss the information.
     * Some case alarm is associated with some resource but for the same resource prov may not
     * be associated. In this case prov should not register for those resource with COR.
     */
    rc = clCorMoIdToMoClassPathGet( pFullMoId, &moPath );
    rc = clCorMSOClassExist( &moPath, CL_COR_SVC_ID_PROVISIONING_MANAGEMENT );
    if ( CL_OK != rc )
    {
        return rc;
    }

    /*
     * Add to prov resource list 
     */
    memcpy(&pProvMoIdList->moId[pProvMoIdList->moIdCnt], pFullMoId, sizeof(ClCorMOIdT));
    clCorMoIdServiceSet(&pProvMoIdList->moId[pProvMoIdList->moIdCnt], CL_COR_SVC_ID_PROVISIONING_MANAGEMENT);
    pProvMoIdList->moIdCnt++;

    if ( CL_TRUE == wildCardFlag )
    {
        return CL_OK;
    }

    if ( CL_FALSE == createFlag )
    {
        rc = clProvIfCreateFlagIsFalse( pFullMoId, pProvAddr, primaryOIFlag );
        if ( CL_OK != rc )
        {
            return rc;
        }
    }
    else
    {
        rc = clProvIfCreateFlagIsTrue( pFullMoId, pProvAddr, primaryOIFlag, autoCreateFlag );
        if ( CL_OK != rc )
        {
            return rc;
        }
    }

    CL_FUNC_EXIT();
    return rc;
}