//#
//# Time Server
//# Copyright 2004 by Eric Y. Theriault
//# All Rights Reserved.
//# http://www.eyt.ca/CORBA
//#
#ifdef EYT_MICO
#include "Mico/Time.h"
#else
#ifdef EYT_TAO
#include "TAO/TimeS.h"
#else
#error Undefined ORB type.
#endif
#endif
#include <iostream>
#include <fstream>
#include <errno.h>
#include <time.h>

using namespace TimeTools;

namespace {
   class Time_impl : public POA_TimeTools::Time {
   public:
      virtual ~Time_impl()
      {
      }

      // Acquire the time...
      TimeTools::TimeOfDay getTime() throw ( CORBA::SystemException );
   };

   // Acquire the time...
   TimeTools::TimeOfDay Time_impl::getTime() throw ( CORBA::SystemException )
   {
      // Acquire the time
      time_t time_now = time( 0 );
      //TODO: Should probably be localtime_r, but MSVC2003 does not have it.
      struct tm *time = localtime( &time_now );

      // Adapt the time.
      TimeOfDay t;
      t.hour = time->tm_hour;
      t.minute = time->tm_min;
      t.second = time->tm_sec;

      // Return and clean up
      return t;
   }
};

int main( int argc, char ** argv )
{
   std::string iorFile = "time.ior";

   try {
      // Create and Initialize the ORB
      CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );

      // Get a reference to the root POA and activate the POAManager
      CORBA::Object_var rootPOA = orb->resolve_initial_references( "RootPOA" );
      PortableServer::POA_var poa = PortableServer::POA::_narrow( rootPOA );

      // Activate POA manager
      PortableServer::POAManager_var manager = poa->the_POAManager();
      manager->activate();

      // Create the server object
      Time_impl timeImpl;

      // Create the object reference
      Time_var ref = timeImpl._this();
      CORBA::String_var ior = orb->object_to_string( ref );

      // Create the file
      std::ofstream file( iorFile.c_str(), std::ios::out );
      if ( file.fail() ) {
         std::cerr << "Cannot open " << iorFile.c_str() << ": "
                   << strerror( errno ) << std::endl;
         return 1;
      }
      file << ior;
      file.close();
      if ( file.fail() ) {
         std::cerr << "Cannot open " << iorFile.c_str() << ": "
                   << strerror( errno ) << std::endl;
         return 1;
      }

      // Accept requests
      std::cout << "TimeServer is ready and waiting..." << std::endl;
      orb->run();
   } catch ( const CORBA::Exception & e ) { 
      std::cerr << "Caught a CORBA exception." << std::endl;
#ifdef EYT_MICO
      e._print( std::cerr );
      std::cerr << std::endl;
#else
#ifdef EYT_TAO
      std::cerr << e._name() << std::endl;
#else
#error Need a more verbose error here.
#endif
#endif
      return 1;
   } catch ( const std::exception & e ) { 
      std::cerr << "Caught Exception: " << e.what() << std::endl;
      return 1;
   } catch ( ... ) { 
      std::cerr << "Unknown exception caught." << std::endl;
      return 1;
   }
}

