// **********************************************************************
//
// Copyright (c) 1999
// Object Oriented Concepts, Inc.
// Billerica, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#include <assert.h>
#include <stdlib.h>
#include <string.h>

#include <OB/CORBA.h>
#include <OB/Util.h>

#include <OB/OBNaming.h>

#include "TestObject_impl.h"
#include "TestMacro.h"


//
// Test CosNaming::OBNamingContext::list_extended()
//
void
TestListExtended(CORBA_ORB_ptr orb, CosNaming_NamingContext_ptr root)
{
    CosNaming_OBNamingContext_var ext =
        CosNaming_OBNamingContext::_narrow(root);
    assert(! CORBA_is_nil(ext));

    TestObject_var test = new TestObject_impl;
    CosNaming_Name name1;
    CosNaming_OBNamingContext::ExtendedBindingList_var list;

    CosNaming_NamingContext_var context = ext -> new_context();

    //
    // Add some bindings to test list_extended()
    //
    name1.length(1);
    name1[0].id = CORBA_string_dup("obj1");
    name1[0].kind = CORBA_string_dup("kind1");
    SUCCEED(ext -> bind(name1, test));
    name1[0].id = CORBA_string_dup("obj2");
    SUCCEED(ext -> bind(name1, test));
    name1[0].id = CORBA_string_dup("obj3");
    SUCCEED(ext -> bind(name1, test));
    name1[0].id = CORBA_string_dup("context");
    SUCCEED(ext -> bind_context(name1, context));

    list = ext -> list_extended();
    assert(list -> length() == 4);

    CORBA_Long tsObj1 = 0, tsObj2 = 0, tsObj3 = 0, tsContext = 0; // timestamps

    //
    // Check BindingType and timestamp
    //
    for(CORBA_ULong i = 0 ; i < list -> length() ; i++)
    {
        assert(list[i].timestamp > 0);

        //
        // Remember timestamps
        //
        if(strcmp(list[i].binding_name[0].id, "obj1") == 0)
           tsObj1 = list[i].timestamp;
        else if(strcmp(list[i].binding_name[0].id, "obj2") == 0)
           tsObj2 = list[i].timestamp;
        else if(strcmp(list[i].binding_name[0].id, "obj3") == 0)
           tsObj3 = list[i].timestamp;
        else if(strcmp(list[i].binding_name[0].id, "context") == 0)
           tsContext = list[i].timestamp;

        if(strcmp(list[i].binding_name[0].id, "obj1") == 0 ||
           strcmp(list[i].binding_name[0].id, "obj2") == 0 ||
           strcmp(list[i].binding_name[0].id, "obj3") == 0)
            assert(list[i].ncOrObj._d() == CosNaming_nobject);
        else if(strcmp(list[i].binding_name[0].id, "context") == 0)
            assert(list[i].ncOrObj._d() == CosNaming_ncontext);
        else
            assert("unknown binding in list" == 0);
    }

    //
    // Verify timestamps - check order of creation
    //
    assert(tsContext >= tsObj3 && tsObj3 >= tsObj2 && tsObj2 >= tsObj1);

    //
    // Remove a binding and test again
    //
    name1[0].id = CORBA_string_dup("obj2");
    SUCCEED(ext -> unbind(name1));
    list = ext -> list_extended();
    assert(list -> length() == 3);

    //
    // Remove all bindings and test again
    //
    name1[0].id = CORBA_string_dup("obj1");
    SUCCEED(ext -> unbind(name1));
    name1[0].id = CORBA_string_dup("obj3");
    SUCCEED(ext -> unbind(name1));
    name1[0].id = CORBA_string_dup("context");
    SUCCEED(ext -> unbind(name1));
    list = ext -> list_extended();
    assert(list -> length() == 0);

    SUCCEED(context -> destroy());
}
