/*
  client.cpp

  This is the simplest Corba client which connects to a "Hello World" server.
  This is done via a poor-man naming service, a file-based IOR.

  Author: Ingo Kloeckl
 */

#include <OB/CORBA.h>
#include <Hallo.h>    // header from IDL module
#include <stdlib.h>
#include <string>

using namespace std;

int main(int argc, char*argv[], char*[]){
  int status = EXIT_SUCCESS;
  CORBA::ORB_var orb;

  try {
    // first, get the ORB reference
    orb = CORBA::ORB_init(argc, argv);
  } catch (const CORBA::SystemException& e){
    cerr << "Error initializing ORB: " << e << endl;
    return EXIT_FAILURE;
  }

  // Now get the reference to the server object by reading its IOR from file.
  // After narrowing to 'Hallo', the oServer object is no longer needed
  // It is therefore very convenient that try/catch builds a scope for
  // the temporary oServer variable :-) We only have to ensure that the
  // variable for the narrowed server reference is available outside the
  // try/catch scope
  Hallo_var server;
  try {
    // read IOR from file and converts it into an object reference
    CORBA::Object_var oServer = orb->string_to_object("relfile:/HAL.ref");
    if (CORBA::is_nil(oServer)){
      cerr << argv[0] << ": no server under the specified IOR, exiting" << endl;
      return EXIT_FAILURE;
    }

    // narrow down server object to the 'Hallo' interface
    server = Hallo::_narrow(oServer);
    if (CORBA::is_nil(server)){
      cerr << argv[0] << ": server is not a 'Hallo' object, exiting" << endl;
      return EXIT_FAILURE;
    }
  } catch (const CORBA::TRANSIENT& e) {
    cerr << argv[0] << ": server not reachable, exiting" << endl;
    return EXIT_FAILURE;
  } catch (const CORBA::BAD_PARAM& e) {
    cerr << argv[0] << ": incorrect IOR format, exiting" << endl;
    return EXIT_FAILURE;
  } catch (const CORBA::SystemException& e) {
    cerr << argv[0] << ": error resolving reference to server, " << e << endl;
    return EXIT_FAILURE;
  }

  try {
    // finally use that boring server object
    server->sayHi();
    string name = server->name();
    cout << "The servers's name is " << name << endl;
    server->sayHi();

    // shut down the server. This should normally be done by an authorized person
    // who is very important (a manager, for example). Present this function to him
    // by visualizing it as big red important button :-)
    //    server->shutdown();

    // OK, thats all
  } catch (const CORBA::Exception& e){
    cerr << "Error: " << e << endl;
    status = EXIT_FAILURE;
  }

  // if out superuser has not stopped the ORB, we simply destroy it now
  if (!CORBA::is_nil(orb)){
    try {
      orb->destroy();
    } catch (const CORBA::SystemException& e){
      cerr << e << endl;
      status = EXIT_FAILURE;
    }
  }

  return status;
}

