// **********************************************************************
//
// 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/CosNaming.h>

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


//
// Test CosNaming::NamingContext::list() and CosNaming::BindingIterator
//
void
TestList(CORBA_ORB_ptr orb, CosNaming_NamingContext_ptr root)
{
    TestObject_var test1 = new TestObject_impl;
    TestObject_var test2 = new TestObject_impl;
    TestObject_var test3 = new TestObject_impl;
    CosNaming_Name name;
    CosNaming_BindingList_var list;
    CosNaming_BindingIterator_var iter;
    CosNaming_Binding_var binding;

    CosNaming_NamingContext_var context = root -> new_context();

    name.length(1);
    name[0].id = CORBA_string_dup("obj1");
    name[0].kind = CORBA_string_dup("kind1");
    SUCCEED(root -> bind(name, test1));
    name[0].id = CORBA_string_dup("obj2");
    SUCCEED(root -> bind(name, test2));
    name[0].id = CORBA_string_dup("obj3");
    SUCCEED(root -> bind(name, test3));
    name[0].id = CORBA_string_dup("context");
    SUCCEED(root -> bind_context(name, context));

    root -> list(4, list.out(), iter.out());
    assert(list -> length() == 4);
    assert(CORBA_is_nil(iter));

    for(CORBA_ULong i = 0 ; i < list -> length() ; i++)
    {
        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].binding_type == CosNaming_nobject);
        else if(strcmp(list[i].binding_name[0].id, "context") == 0)
            assert(list[i].binding_type == CosNaming_ncontext);
        else
            assert("unknown binding in list" == 0);
    }

    root -> list(2, list.out(), iter.out());
    assert(list -> length() == 2);
    assert(! CORBA_is_nil(iter));
    assert(iter -> next_one(binding));
    assert(iter -> next_one(binding));
    assert(! iter -> next_one(binding)); // no more
    iter -> destroy();

    root -> list(0, list.out(), iter.out());
    assert(list -> length() == 0);
    assert(! CORBA_is_nil(iter));
    try
    {
	assert(iter -> next_n(0, list));
	assert("Call to next_n(0) should not have succeeded." == 0);
    }
    catch(const CORBA_BAD_PARAM&)
    {
	// Expected
    }
    assert(list -> length() == 0);
    assert(iter -> next_n(3, list));
    assert(list -> length() == 3);
    assert(iter -> next_n(1, list));
    assert(list -> length() == 1);
    assert(! iter -> next_n(1, list)); // no more
    iter -> destroy();

    //
    // Clean up
    //
    name.length(1);
    name[0].id = CORBA_string_dup("obj1");
    name[0].kind = CORBA_string_dup("kind1");
    SUCCEED(root -> unbind(name));
    name[0].id = CORBA_string_dup("obj2");
    SUCCEED(root -> unbind(name));
    name[0].id = CORBA_string_dup("obj3");
    SUCCEED(root -> unbind(name));
    name[0].id = CORBA_string_dup("context");
    SUCCEED(root -> unbind(name));
    SUCCEED(context -> destroy());
}
