//
// Derived from the Hello example of OmniBroker 1.0
//

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

#include <stdio.h>
#include <stdlib.h>

#include <string>

#include "viciface_impl.h"

int main(int argc, char* argv[])
{
#if 0
    if (argc != 1)
    {
        cerr << "Usage: " << argv[0];
        exit(0);
    }
#endif

    // scope is rest of the program for these variables
    // 
    CosNaming_NamingContext_var nc;
    vic_control_var p;
    CosNaming_Name test;

    try
    {
	// Create ORB and BOA
	//
	CORBA_ORB_var orb = CORBA_ORB_init(argc, argv);
	CORBA_BOA_var boa = orb->BOA_init(argc, argv);

        CORBA_Object_var obj;
        
        try
        {
            obj = orb->resolve_initial_references("NameService");
        }
        catch(const CORBA_ORB::InvalidName &ex)
        {
            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;
        }

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

        //
        // Create and bind some Naming Contexts
        //
        try
        {
            
            CosNaming_Name nc1Name;
            nc1Name.length(1);
            nc1Name[0].id = CORBA_string_dup("vics");
            nc1Name[0].kind = CORBA_string_dup("");
            CosNaming_NamingContext_var nc1 = nc->bind_new_context(nc1Name);
        }
        catch(const CosNaming_NamingContext::AlreadyBound &ex)
        {
            cout << "Naming context already Bound. " << endl;
            delete &ex;
        }

        //
        // Create implementation object
        //
        p = new vic_control_impl();

        try
        {
            test.length(2);
            test[0].id = CORBA_string_dup("vics");
            test[0].kind = CORBA_string_dup("");
            test[1].id = CORBA_string_dup("v1");
            test[1].kind = CORBA_string_dup("");
            nc->bind(test, p);
        }
        catch(const CosNaming_NamingContext::AlreadyBound &ex)
        {
            cout << "Object name already Bound. Rebind" << endl;
            nc->rebind(test, p);
            cout << "Rebind OK" << endl;
            delete &ex;
        }

        // Run implementation
        // Since pf isn't used calling impl_is_ready is OK.
        //
        cout << "Running implementation" << endl;
        boa->impl_is_ready(CORBA_ImplementationDef::_nil());
        
        nc->unbind(test);
    }
    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 &ex)
    {
        cerr << argv[0] << ": Got a `CannotProceed' exception" << endl;
        return 1;
    }
    catch(const CosNaming_NamingContext::InvalidName &ex)
    {
        cerr << argv[0] << ": Got an `InvalidName' exception" << endl;
        return 1;
    }
    catch(const CosNaming_NamingContext::AlreadyBound &ex)
    {
        cout << "Something is already bound???" << endl;
        // Already bound, rebind
        nc->rebind(test, p);
        cout << "Rebind OK" << endl;

    }
    catch(const CosNaming_NamingContext::NotEmpty &ex)
    {
        cerr << argv[0] << ": Got a `NotEmpty' exception" << endl;
        return 1;
    }
#ifdef __GNUG__
    catch(CORBA_COMM_FAILURE& ex)
#else
    catch(CORBA_SystemException& ex)
#endif
    {
	OBPrintException(ex);
	return 1;
    }
    catch(vic_control::error &ex)
    {
        cout << ex.reason << endl;
        return 1;
    }
    
    return 0;
}


