TEST(cps_api_key,key_insert) {
    cps_api_key_t key;
    memset(&key,0,sizeof(key));
    cps_api_key_set(&key,0,0);
    cps_api_key_set(&key,1,1);
    cps_api_key_set(&key,2,2);
    cps_api_key_set_len(&key,3);

    cps_api_key_t new_key ;
    cps_api_key_copy(&new_key,&key);


    cps_api_key_remove_element(&new_key,0);
    ASSERT_TRUE(cps_api_key_element_at(&new_key,0)== 1);
    ASSERT_TRUE(cps_api_key_get_len(&new_key)==2);

    cps_api_key_insert_element(&new_key,0,5);
    ASSERT_TRUE(cps_api_key_element_at(&new_key,0)== 5);
    ASSERT_TRUE(cps_api_key_get_len(&new_key)==3);

    cps_api_key_insert_element(&new_key,3,5);
    ASSERT_TRUE(cps_api_key_element_at(&new_key,3)== 5);
    ASSERT_TRUE(cps_api_key_get_len(&new_key)==4);

    cps_api_key_insert_element(&new_key,2,5);
    ASSERT_TRUE(cps_api_key_element_at(&new_key,2)== 5);
    ASSERT_TRUE(cps_api_key_get_len(&new_key)==5);

    ASSERT_TRUE(cps_api_key_element_at(&new_key,0)== 5);
    ASSERT_TRUE(cps_api_key_element_at(&new_key,2)== 5);
    ASSERT_TRUE(cps_api_key_element_at(&new_key,4)== 5);

}
void cps_api_key_init(cps_api_key_t * key,
        cps_api_qualifier_t qual,
        cps_api_object_category_types_t cat,
        cps_api_object_subcategory_types_t subcat, size_t number_of_inst, ...) {

    va_list v;

    cps_api_key_set_attr(key,0);
    size_t key_len = 0;

    if (qual!=0) {
        cps_api_key_set(key,CPS_OBJ_KEY_INST_POS,qual);
        ++key_len;
    }

    if ((key_len > CPS_OBJ_KEY_INST_POS) && cat!=0) {
        cps_api_key_set(key,CPS_OBJ_KEY_CAT_POS,cat);
        ++key_len;
    }
    if ((key_len > CPS_OBJ_KEY_CAT_POS) && subcat!=0) {
        cps_api_key_set(key,CPS_OBJ_KEY_SUBCAT_POS,subcat);
        ++key_len;
    }
    if (key_len >CPS_OBJ_KEY_SUBCAT_POS) {
        size_t ix = 0;
        size_t mx = number_of_inst;
        va_start(v,number_of_inst);
        for ( ; ix < mx ; ++ix ) {
            int val = va_arg(v,int);

            cps_api_key_set(key,CPS_OBJ_KEY_APP_INST_POS+ix,val);
            ++key_len;
        }
        va_end(v);
    }
TEST(cps_api_key,key_create) {
    cps_api_key_t key;
    memset(&key,0,sizeof(key));
    cps_api_key_set(&key,0,0);
    cps_api_key_set(&key,1,1);
    cps_api_key_set(&key,2,2);
    cps_api_key_set_len(&key,3);

    ASSERT_TRUE(cps_api_key_get_len(&key)==3);
    ASSERT_TRUE(cps_api_key_element_at(&key,0)==0);
    ASSERT_TRUE(cps_api_key_element_at(&key,1)==1);
    ASSERT_TRUE(cps_api_key_element_at(&key,2)==2);

}
TEST(cps_api_key,key_compare) {
    char buff1[1024];
    char buff2[1024];

    cps_api_key_t key;
    memset(&key,0,sizeof(key));
    cps_api_key_set(&key,0,1);
    cps_api_key_set(&key,1,3);
    cps_api_key_set(&key,2,1);
    cps_api_key_set(&key,3,1);
    cps_api_key_set_len(&key,4);

    cps_api_key_t key2;
    memset(&key2,0,sizeof(key2));
    cps_api_key_set(&key2,0,1);
    cps_api_key_set(&key2,1,3);
    cps_api_key_set(&key2,2,1);
    cps_api_key_set(&key2,3,1);
    cps_api_key_set_len(&key2,4);
    ASSERT_TRUE(cps_api_key_matches(&key,&key2,false)==0);

    cps_api_key_set(&key2,1,4);
    ASSERT_TRUE(cps_api_key_matches(&key,&key2,false)!=0);

    cps_api_key_set(&key2,1,3);
    cps_api_key_set(&key2,4,2);
    cps_api_key_set_len(&key2,3);
    ASSERT_TRUE(cps_api_key_matches(&key,&key2,false)==0);

    cps_api_key_set(&key2,1,2);
    cps_api_key_set_len(&key2,4);
    ASSERT_TRUE(cps_api_key_matches(&key,&key2,false)!=0);

    cps_api_key_t key3;
    memset(&key3,0,sizeof(key3));
    cps_api_key_set(&key3,0,1);
    cps_api_key_set(&key3,1,3);
    cps_api_key_set(&key3,2,1);
    cps_api_key_set_len(&key3,3);

    ASSERT_TRUE(cps_api_key_matches(&key,&key3,true)!=0);
    cps_api_key_set_len(&key3,1);
    ASSERT_TRUE(cps_api_key_matches(&key,&key3,false)==0);
    cps_api_key_set_len(&key3,2);
    ASSERT_TRUE(cps_api_key_matches(&key,&key3,false)==0);

    cps_api_key_set(&key2,1,3);
    ASSERT_TRUE(cps_api_key_matches(&key,&key2,true)==0);
    printf("Key 1 %s, Key 2 %s\n",cps_api_key_print(&key,buff1,sizeof(buff1)),
            cps_api_key_print(&key2,buff2,sizeof(buff2)));

    cps_api_key_set_len(&key2,2);
    cps_api_key_set(&key2,2,4);

    ASSERT_TRUE(cps_api_key_matches(&key,&key2,false)==0);
    printf("Key 1 %s, Key 2 %s\n",cps_api_key_print(&key,buff1,sizeof(buff1)),
            cps_api_key_print(&key2,buff2,sizeof(buff2)));

    ASSERT_TRUE(cps_api_key_matches(&key2,&key,false)!=0);

    cps_api_key_set(&key2,2,2);
    cps_api_key_set(&key,2,0);

    ASSERT_TRUE(cps_api_key_matches(&key,&key2,false)==0);

    printf("Key 1 %s, Key 2 %s\n",cps_api_key_print(&key,buff1,sizeof(buff1)),
            cps_api_key_print(&key2,buff2,sizeof(buff2)));

    memset(&key2,0,sizeof(key2));
    cps_api_key_copy(&key2,&key);

    ASSERT_TRUE(cps_api_key_matches(&key,&key2,true)==0);

    printf("Final\nKey 1 %s, Key 2 %s\n",cps_api_key_print(&key,buff1,sizeof(buff1)),
            cps_api_key_print(&key2,buff2,sizeof(buff2)));
}
static cps_api_return_code_t _phy_set(cps_api_object_t req, cps_api_object_t prev) {
    STD_ASSERT(prev!=nullptr && req!=nullptr);

    cps_api_object_attr_t _npu = cps_api_get_key_data(req,BASE_IF_PHY_PHYSICAL_NPU_ID);
    cps_api_object_attr_t _port = cps_api_get_key_data(req,BASE_IF_PHY_PHYSICAL_PORT_ID);

    if (_npu==nullptr || _port==nullptr) {
        EV_LOG(ERR,INTERFACE,0,"NAS-PHY","Set req missing key instances");
        return cps_api_ret_code_ERR;
    }

    npu_id_t npu = cps_api_object_attr_data_u32(_npu);
    port_t port = cps_api_object_attr_data_u32(_port);

    if (_is_cpu_port(npu, port)) {
        EV_LOG(ERR,INTERFACE,0,"NAS-PHY","Can't modify the CPU port %d:%d",npu,port);
        return cps_api_ret_code_ERR;
    }

    uint32_t hwport;
    if (!get_hw_port(npu,port,hwport)) {
        return cps_api_ret_code_ERR;
    }

    cps_api_object_attr_t _fp = cps_api_get_key_data(req,BASE_IF_PHY_PHYSICAL_FRONT_PANEL_NUMBER);
    cps_api_object_attr_t _media_type = cps_api_get_key_data(req,BASE_IF_PHY_PHYSICAL_PHY_MEDIA);
    cps_api_object_attr_t _loopback = cps_api_get_key_data(req,BASE_IF_PHY_PHYSICAL_LOOPBACK);

    auto it = _phy_port.find(hwport);
    if (it == _phy_port.end()) {
        _phy_port[hwport].front_panel_port = 0;
        _phy_port[hwport].sub_port = 0;
        _phy_port[hwport].media_type = 0;
        _phy_port[hwport].loopback = 0;
    }

    if (_fp!=nullptr) {
        _phy_port[hwport].front_panel_port = cps_api_object_attr_data_u32(_fp);
    }

    if (_media_type != nullptr) {
        PLATFORM_MEDIA_TYPE_t media_type = (PLATFORM_MEDIA_TYPE_t) cps_api_object_attr_data_u32(_media_type);
        if (_phy_port[hwport].media_type != media_type) {
            if (_phy_media_type_with_default_config_set(npu, port, media_type) != STD_ERR_OK)  {
                EV_LOG(ERR,INTERFACE,0,"NAS-PHY","Failed to set phy media type for %d:%d",npu,port);
                return cps_api_ret_code_ERR;
            }
            _phy_port[hwport].media_type = media_type;
        }
    }

    if (_loopback != nullptr) {
        if (ndi_port_loopback_set(npu, port,
                    (BASE_CMN_LOOPBACK_TYPE_t) cps_api_object_attr_data_u32(_loopback)) != STD_ERR_OK)  {
            EV_LOG(ERR,INTERFACE,0,"NAS-PHY","Failed to set loopback for %d:%d",npu,port);
            return cps_api_ret_code_ERR;
        }
        _phy_port[hwport].loopback = cps_api_object_attr_data_u32(_loopback);
    }
    cps_api_key_set(cps_api_object_key(req),CPS_OBJ_KEY_INST_POS,cps_api_qualifier_OBSERVED);
    hal_interface_send_event(req);
    cps_api_key_set(cps_api_object_key(req),CPS_OBJ_KEY_INST_POS,cps_api_qualifier_TARGET);

    return cps_api_ret_code_OK;
}