#include "tp1_i.hh"


static CORBA::Boolean bindObjectToName(CORBA::ORB_ptr, CORBA::Object_ptr);

int main(int argc, char** argv)
{
  try {
    // Initialise the ORB.
    CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, "omniORB3");

    // Obtain a reference to the root POA.
    CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
    PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);

    // We allocate the objects on the heap.  Since these are reference
    // counted objects, they will be deleted by the POA when they are no
    // longer needed.
    bookmark_i* mybookmark_i = new bookmark_i();
    
    // Activate the objects.  This tells the POA that the objects are
    // ready to accept requests.
    PortableServer::ObjectId_var mybookmark_iid = poa->activate_object(mybookmark_i);
    
    // IDL interface: bookmark
    CORBA::Object_var ref = mybookmark_i->_this();
    if (!bindObjectToName(orb,ref) ) return 1;
    
    mybookmark_i->_remove_ref();

    // Obtain a POAManager, and tell the POA to start accepting
    // requests on its objects.
    PortableServer::POAManager_var pman = poa->the_POAManager();
    pman->activate();

    orb->run();
    orb->destroy();
  }
  catch(CORBA::SystemException&) {
    cerr << "Caught CORBA::SystemException." << endl;
  }
  catch(CORBA::Exception&) {
    cerr << "Caught CORBA::Exception." << endl;
  }
  catch(omniORB::fatalException& fe) {
    cerr << "Caught omniORB::fatalException:" << endl;
    cerr << "  file: " << fe.file() << endl;
    cerr << "  line: " << fe.line() << endl;
    cerr << "  mesg: " << fe.errmsg() << endl;
  }
  catch(...) {
    cerr << "Caught unknown exception." << endl;
  }

  return 0;
}

// fonction enregistrant l'objet objref dans le service de nommage
static CORBA::Boolean bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref)
{
	CosNaming::NamingContext_var rootContext;

	try
	{
		// obtain a reference to the root context of the Name service
		CORBA::Object_var obj;
		obj = orb->resolve_initial_references("NameService");

		// narrow the reference returned
		rootContext = CosNaming::NamingContext::_narrow(obj);
		if (CORBA::is_nil(rootContext))
		{
			cerr << "Impossible de recuperer le service de nommage" << endl;
			return 0;
		}
	}
	catch (CORBA::ORB::InvalidName& ex)
	{
		// this should not happen!
		cerr << "Service invalide." << endl;
		return 0;
	}
	
	
	try
	{
	/*
		CosNaming::Name contextName;
		contextName.length(1);
		contextName[0].id = (const char*) "/";
		contextName[0].kind = (const char*) "contexte";
		CosNaming::NamingContext_var testContext;
		try
		{
			testContext = rootContext->bind_new_context(contextName);
		}
		catch(CosNaming::NamingContext::AlreadyBound& ex)
		{
			// si le contexte existe deja une exception est levee
			// dans ce cas, il faut recuperer le nom et lui affecter le contexte
			CORBA::Object_var obj = rootContext->resolve(contextName);
			testContext = CosNaming::NamingContext::_narrow(obj);
			if (CORBA::is_nil(testContext))
			{
				cerr << "Impossible de recuperer le contexte." << endl;
				return 0;
			}
		}
	*/
		CosNaming::Name objectName;
		objectName.length(1);
		objectName[0].id = (const char*) "Bookmark";
		objectName[0].kind = (const char*) "Objet";
		try
		{
			rootContext->bind(objectName,objref);
		}
		catch(CosNaming::NamingContext::AlreadyBound& ex)
		{
			rootContext->rebind(objectName,objref);
		}
	}
	catch(CORBA::COMM_FAILURE& ex)
	{
		cerr << "Caught system exception COMM_FAILURE -- unable to contact the name service" << endl;
		return 0;
	}
	
	return 1;
}
