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

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

#include <NamingExample_impl.h>

int
main(int argc, char* argv[], char*[])
{
    try
    {
	//
	// Create ORB
	//
	CORBA_ORB_var orb = CORBA_ORB_init(argc, argv);
	
	//
	// Create BOA
	//
	CORBA_BOA_var boa = orb -> BOA_init(argc, argv);

	//
	// Create some implementations
	//
	Named_var a = new Named_impl;
	Named_var a1 = new Named_impl;
	Named_var a2 = new Named_impl;
	Named_var a3 = new Named_impl;
	Named_var b = new Named_impl;
	Named_var c = new Named_impl;

	//
	// Get naming service
	//
	CORBA_Object_var obj;

	try
	{
	    obj = orb -> resolve_initial_references("NameService");
	}
	catch(const CORBA_ORB::InvalidName&)
	{
	    cerr << argv[0] << ": can't resolve `NameService'" << endl;
	    return 1;
	}

	if(CORBA_is_nil(obj))
	{
	    cerr << argv[0] << ": `NameService' is a nil object reference"
		 << endl;
	    return 1;
	}

	CosNaming_NamingContext_var nc = CosNaming_NamingContext::_narrow(obj);

	if(CORBA_is_nil(nc))
	{
	    cerr << argv[0]
		 << ": `NameService' is not a NamingContext object reference"
		 << endl;
	    return 1;
	}

	try
	{
	    //
	    // Create and bind some Naming Contexts
	    //
	    CosNaming_Name nc1Name;
	    nc1Name.length(1);
	    nc1Name[0].id = CORBA_string_dup("nc1");
	    nc1Name[0].kind = CORBA_string_dup("");
	    CosNaming_NamingContext_var nc1 = nc -> bind_new_context(nc1Name);

	    CosNaming_Name nc2Name;
	    nc2Name.length(2);
	    nc2Name[0].id = CORBA_string_dup("nc1");
	    nc2Name[0].kind = CORBA_string_dup("");
	    nc2Name[1].id = CORBA_string_dup("nc2");
	    nc2Name[1].kind = CORBA_string_dup("");
	    CosNaming_NamingContext_var nc2 = nc -> bind_new_context(nc2Name);

	    //
	    // Bind names with the Naming Service
	    //
	    CosNaming_Name aName;
	    aName.length(1);
	    aName[0].id = CORBA_string_dup("a");
	    aName[0].kind = CORBA_string_dup("");
	    nc -> bind(aName, a);

	    CosNaming_Name a1Name;
	    a1Name.length(1);
	    a1Name[0].id = CORBA_string_dup("a1");
	    a1Name[0].kind = CORBA_string_dup("");
	    nc -> bind(a1Name, a1);

	    CosNaming_Name a2Name;
	    a2Name.length(1);
	    a2Name[0].id = CORBA_string_dup("a2");
	    a2Name[0].kind = CORBA_string_dup("");
	    nc -> bind(a2Name, a2);

	    CosNaming_Name a3Name;
	    a3Name.length(1);
	    a3Name[0].id = CORBA_string_dup("a3");
	    a3Name[0].kind = CORBA_string_dup("");
	    nc -> bind(a3Name, a3);

	    CosNaming_Name bName;
	    bName.length(2);
	    bName[0].id = CORBA_string_dup("nc1");
	    bName[0].kind = CORBA_string_dup("");
	    bName[1].id = CORBA_string_dup("b");
	    bName[1].kind = CORBA_string_dup("");
	    nc -> bind(bName, b);

	    CosNaming_Name cName;
	    cName.length(3);
	    cName[0].id = CORBA_string_dup("nc1");
	    cName[0].kind = CORBA_string_dup("");
	    cName[1].id = CORBA_string_dup("nc2");
	    cName[1].kind = CORBA_string_dup("");
	    cName[2].id = CORBA_string_dup("c");
	    cName[2].kind = CORBA_string_dup("");
	    nc -> bind(cName, b);

	    //
	    // Run implementation
	    //
	    boa -> impl_is_ready(CORBA_ImplementationDef::_nil());

	    //
	    // Unregister names with the Naming Service
	    //
	    nc -> unbind(cName);
	    nc -> unbind(bName);
	    nc -> unbind(aName);
	    nc -> unbind(nc2Name);
	    nc -> unbind(nc1Name);
	}
	catch(const CosNaming_NamingContext::NotFound& ex)
	{
	    cerr << argv[0] << ": Got a `NotFound' exception (";
	    switch(ex.why)
	    {
	    case CosNaming_NamingContext::missing_node:
		cerr << "missing node";
		break;

	    case CosNaming_NamingContext::not_context:
		cerr << "not context";
		break;

	    case CosNaming_NamingContext::not_object:
		cerr << "not object";
		break;
	    }
	    cerr << ")" << endl;
	    return 1;
	}
	catch(const CosNaming_NamingContext::CannotProceed&)
	{
	    cerr << argv[0] << ": Got a `CannotProceed' exception" << endl;
	    return 1;
	}
	catch(const CosNaming_NamingContext::InvalidName&)
	{
	    cerr << argv[0] << ": Got an `InvalidName' exception" << endl;
	    return 1;
	}
	catch(const CosNaming_NamingContext::AlreadyBound&)
	{
	    cerr << argv[0] << ": Got an `AlreadyBound' exception" << endl;
	    return 1;
	}
	catch(const CosNaming_NamingContext::NotEmpty&)
	{
	    cerr << argv[0] << ": Got a `NotEmpty' exception" << endl;
	    return 1;
	}
    }
    catch(const CORBA_SystemException& ex)
    {
	OBPrintException(ex);
	return 1;
    }

    return 0;
}
