/*******************************************************************************
* E.S.O. - ACS project
*
* "@(#) $Id: maciContainer.cpp,v 1.5 2003/10/23 08:06:25 acaproni Exp $"
*
* who       when      what
* --------  --------  ----------------------------------------------
* david 2002-08-15 changed argUnpack.h to acsutilArgUnpack.h
* bgustafs 2002-04-15 corrected activator shutdown on VxWorks
* bgustafs 2001-07-12 added namespace declarations
* msekoran  2001/02/21  created 
*/

/** @file maciContainer.cpp
 *  maciContainer is used to start an Container on the workstation or LCU.  There are many different
 *  parameters which can be passed to maciContainer, but only the container we want to start is required.
 *  @htmlonly
 *  <br><br>
 *  @endhtmlonly

 *  @param container This is simply the name of the container in the CDB that we want to start.
 *  @htmlonly
 *  <br><hr>
 *  @endhtmlonly

 *  @param "-r" Use this optional parameter to run container in recovery mode.
 *  @htmlonly
 *  <br><hr>
 *  @endhtmlonly

 *  @param "-p filename" Use this optional parameter to write out the process ID of this container to filename.
 *  @htmlonly
 *  <br><hr>
 *  @endhtmlonly

 *  @param "-m corbaloc::$HOSTNAME:xxxx/Manager" Use this optional parameter to run this container with a 
 *  manager running on a port other than 3000 or for a manager on a different PC.
 *  @htmlonly
 *  <br><hr>
 *  @endhtmlonly

 *  @param "-ORBEndpoint iiop://$HOST:xxxx" Use this optional parameter to specify which host/port container
 *  should run on.
 *  @htmlonly
 *  <br><hr>
 *  @endhtmlonly

 *  @param "-ORBInitRef NameService=corbaloc::$HOST:xxxx/NameService" Use this optional parameter to specify which 
 *  host/port container should get a reference to the naming service from.
 *  @htmlonly
 *  <br><hr>
 *  @endhtmlonly

 *  @param "-ORBInitRef NotifyEventChannelFactory=corbaloc::$HOST:xxxx/NotifyEventChannelFactory" Use this optional 
 *  parameter to specify which host/port container should get a reference to the notification service from.
 *  @htmlonly
 *  <br><hr>
 *  @endhtmlonly
 */   


#include <vltPort.h>
#include <acsutil.h>
#include <maciContainerImpl.h>
#include <ace/Arg_Shifter.h>
#include "ECCS.h"

#include <maciHelper.h>

#ifdef MAKE_VXWORKS
#	include "rebootLib.h"
#	include "acsutilArgUnpack.h"

int g_containerShutdownAction = 0;

#endif

NAMESPACE_USE(maci);

ACE_RCSID(maci, maciContainer, "$Id: maciContainer.cpp,v 1.5 2003/10/23 08:06:25 acaproni Exp $")

bool shutting_down = false;


void TerminationSignalHandler(int)
{
  if (shutting_down) return;
  shutting_down=true;

  // initialize logger (TTS has to be initialized)
  if (ContainerImpl::getLogger())
    {
      LoggingProxy::init(ContainerImpl::getLogger());
      LoggingProxy::ThreadName("termination");
    }

  ACS_LOG(0, "termination", (LM_INFO, "Termination signal detected."));

  MACIHelper::terminateResolving();

  
  ACE_TRY
    {
      if (ContainerImpl::getContainer() && 
	  ContainerImpl::getContainer()->getContainerCORBAProxy() != maci::Container::_nil())
        {
	  ContainerImpl::getContainer()->getContainerCORBAProxy()->shutdown(CONTAINER_EXIT << 8);
	  //ContainerImpl::getContainer()->shutdown(CONTAINER_EXIT << 8);
	  
	}
    }
  ACE_CATCHANY
    {
      ACE_PRINT_EXCEPTION(ACE_ANY_EXCEPTION, "TerminationSignalHandler");
    }
  ACE_ENDTRY;
}




int main(int argc, char *argv[])
{
  ACS_SHORT_LOG((LM_INFO, "Starting Container...\n"));

  ACE_OS::signal(SIGINT,  TerminationSignalHandler);  // Ctrl+C
  ACE_OS::signal(SIGTERM, TerminationSignalHandler);  // termination request

  ccsCOMPL_STAT stat;

  stat = ccsInit("vltccs");
  if(stat == FAILURE)
      cout << "Failure with CCS Init !!!!!!" << endl; 

  stat = dbOpen();
  if(stat == FAILURE)
      cout << "Failure with DB OPEN" << endl; 


  ContainerImpl container;

  // while (container.getShutdownAction() == CONTAINER_RELOAD)

  if (container.init(argc, argv))
  {
      // reinitialization of signal handlers is needed, because of CCS
      // the initialization above is needed to stop resolving, etc..
      ACE_OS::signal(SIGINT,  TerminationSignalHandler);  // Ctrl+C
      ACE_OS::signal(SIGTERM, TerminationSignalHandler);  // termination request

      if (container.connect())
	  container.run();
  }

  ACS_SHORT_LOG((LM_INFO, "Stopping container... "));
  
  container.done();

  ACS_SHORT_LOG((LM_INFO, "Container stopped.\n"));

  // reboot/reload action !!!

  if (ContainerImpl::getLogger())
    {
      ContainerImpl::getLogger()->flush();
      ContainerImpl::getLogger()->done();
    }

#ifdef MAKE_VXWORKS
  g_containerShutdownAction = container.getShutdownAction();
#endif

  stat = dbExit();
  if(stat == FAILURE)
      cout << "Failure with CCS Exit!!!!!!" << endl; 

  return container.getStatus();
}



#ifdef MAKE_VXWORKS

int ContainerStart(char *szCmdLn)
{
  int  argc;
  char *argv[100];

  ACE_MAIN_OBJECT_MANAGER

    //ACE_OS::string_to_argv(szCmdLn, argc, argv);

  argc = argUnpack(szCmdLn, argv);
  argv[0] = "Container";

  int retval = ace_main(argc, argv);

  //  1 -- reboot the computer, 2 -- exit the container - both reboot
  if(g_containerShutdownAction == CONTAINER_REBOOT)
    reboot(0);

  // @@ Deallocate argv as required (cf. ContainerImpl)

  return retval;
}

void ContainerStop(int retval)
{
  ContainerImpl * container = ContainerImpl::getContainer();
  
  //  ACE_TRY
  //    {
      if(container != 0)
	{
	container->shutdown(retval);
	//	
	}
      //    }
}

#endif // defined( MAKE_VXWORKS )