//******************************************************************************
//
// Restricted Rights
// WARNING: This is a restricted distribution Zeligsoft file.
//
//******************************************************************************
//
// Copyright (C) 2006 Zeligsoft Inc. - All Rights Reserved
//

//******************************************************************************
//
//     FILE: zceSendReceiveDataMain.cpp
//
//******************************************************************************


#include <iostream>

#include <stdlib.h>

#include "CosNamingC.h"

#include "zceOperatingEnvironment.h"

#include "zceCPPUtilities.h"

#include "zceSendReceiveDataServant.h"

extern zceStatus _status;

int mymain(bool startorb, int argc,char * argv[]);

#ifdef VXWORKS

extern "C" int zceSendReceiveData(
	char * arg0, 
	char * arg1, 
	char * arg2, 
	char * arg3, 
	char * arg4, 
	char * arg5, 
	char * arg6, 
	char * arg7, 
	char * arg8, 
	char * arg9 
	) 
{
	char * myname = "myname";
	int argc      = (int)arg0;
	char ** argv  = (char**)arg1;
	return mymain(false,argc,argv );	
}

#else

int main(int argc, char * argv[])
{
	return mymain(true, argc,argv);
}

#endif

int mymain(bool startorb, int argc, char * argv[])
{
	ZCE_EXC_ENV;
	CORBA::ORB_var orb;
	char* ppszORBArgs[] = {"-ORBendpoint", "-ORBep", "-ORBalternate", "-ORBae", "-ORBsvr_class", "-ORBsc", "-ORBsvr_instance", "-ORBsi", "-ORBmin_recursion", "-ORBmr", "-ORBextra_threads", "-ORBet", "-ORBpriority", "-ORBRTalways_propagate", "-ORBRTap", "-ORBRT", "-ORBretry_delay", "-ORBconn_retries", "-ORBdiag", "-ORBd", "-ORBsync", "-ORBInitRef"};
	int iORBArgc = 22;
	bool bCalculateHostAddress = true;

	_status = ZCE_STATUS_RUNNING;

	REGISTER_PROCESS_TERMINATION_CALLBACK

	if (startorb)
	{
		ZCE_EXC_TRY
		{
			//Swap the ORB* parameter to one starting with a '-'
			for (int i = 0; i < argc; i+=1)
			{
				for (int j = 0; j < iORBArgc; ++j)
				{
					if(str_case_cmp(ppszORBArgs[j]+1, argv[i]) == 0)
					{
						argv[i] = ppszORBArgs[j];
						if((str_case_cmp("-ORBendpoint", argv[i]) == 0) || (str_case_cmp("-ORBep", argv[i]) == 0))
						{
							bCalculateHostAddress = false;
						}
					}
				}
			}

			// initialize the orb
			if(bCalculateHostAddress)
			{
				char pszIPAddress[16];
				char pszORBEndPoint[25]; //pattern is: "<protocol>://AAA.BBB.CCC.DDD:X"
				int newArgc = argc+2;
				char** newArgv = new char*[newArgc];

				get_host_ip_address(pszIPAddress);
				sprintf(pszORBEndPoint, "%s://%s:0", DEFAULT_ORB_PROTOCOL, pszIPAddress);
				for(int k = 0; k < argc; ++k)
				{
					newArgv[k] = argv[k];
				}
				newArgv[argc] = "-ORBendpoint";
				newArgv[argc + 1] = pszORBEndPoint;
				INIT_ORB(orb, newArgc, newArgv, ZCE_MACRO_ENV_ARG)
				delete[] newArgv;
			}
			else
			{
				INIT_ORB(orb, argc, argv, ZCE_MACRO_ENV_ARG)
			}
	
		}
		ZCE_EXC_CATCHANY
		{
			std::cerr << "zceSendReceiveDataMain : Failed to initialize the ORB.";
			_status = ZCE_STATUS_FINISHED;
			return 1;
		}
		ZCE_EXC_ENDTRY(1)
	
	}
	else
	{
		orb = GET_ORB(ZCE_MACRO_ENV_ARG);
	}
	if( CORBA::is_nil( orb ) )
	{
		std::cerr << "zceSendReceiveDataMain : Failed to initialize the ORB.";
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}

	SendReceiveData_params eparams;

	std::string key, value;

	for(int i = 1; i < argc; i++)
	{

		key = argv[i];

		if(++i >= argc) continue;

		value = argv[i];

		// check to see if a switch exists
		if(key[0] == '/' || key[0] == '-')
		{
			// remove the switch
			key.erase(0, 1);
		}
		if(key == "")
		{
			continue;
		}

		if ( key == "NAMING_CONTEXT_IOR" )
		{
			eparams.NAMING_CONTEXT_IOR = value;
		}
		else if ( key == "NAME_BINDING" )
		{
			eparams.NAME_BINDING = value;
		}
		else if ( key == "COMPONENT_IDENTIFIER" )
		{
			eparams.COMPONENT_IDENTIFIER = value;
		}

	}

	if( eparams.NAMING_CONTEXT_IOR.empty() )
	{
		std::cerr << "zceSendReceiveDataMain : Error the NAMING_CONTEXT_IOR execparam is not specified and it is a mandatory.";
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}

	if( eparams.NAME_BINDING.empty() )
	{
		std::cerr << "zceSendReceiveDataMain : Error the NAME_BINDING execparam is not specified and it is a mandatory.";
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}

	if( eparams.COMPONENT_IDENTIFIER.empty() )
	{
		std::cerr << "zceSendReceiveDataMain : Error the COMPONENT_IDENTIFIER execparam is not specified and it is a mandatory.";
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}

	if (startorb) 
	{
		CREATE_ORB_THREAD_POOL(orb, ORB_THREADS_DEFAULT, ZCE_MACRO_ENV_ARG)
	}

	CORBA::Object_var obj;
	PortableServer::POA_var poa;
	PortableServer::POAManager_var mgr;

	std::string objName;
	zceSendReceiveDataServant* component;

		// create the component servant
	component = new zceSendReceiveDataServant( (CORBA::ORB_ptr) orb, eparams ZCE_EXC_ENV_PARAM);

	ZCE_EXC_TRY
	{
		// activate the object
		ACTIVATE_COMPONENT(orb, poa, mgr, obj, component, ZCE_MACRO_ENV_ARG)
	}
	ZCE_EXC_CATCHTYPE(CORBA::SystemException) 
	{
		std::cerr << "zceSendReceiveDataMain : CORBA::SystemException during component activation." << std::endl;
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}
	ZCE_EXC_CATCHTYPE(CORBA::Exception)
 	{
		std::cerr << "zceSendReceiveDataMain : CORBA::Exception during component activation." << std::endl;
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}
	ZCE_EXC_CATCHANY
	{
		std::cerr << "zceSendReceiveDataMain : Unknown exception during component activation." << std::endl;
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}
	ZCE_EXC_ENDTRY(1)

	component->_remove_ref(); //drop ref count

	ZCE_EXC_TRY
	{
		// register with the naming service
		REGISTER_WITH_NAMING_SERVICE(orb, eparams.NAMING_CONTEXT_IOR.c_str(), eparams.NAME_BINDING.c_str(), component, obj, ZCE_MACRO_ENV_ARG)
	}
	ZCE_EXC_CATCHTYPE(CosNaming::NamingContext::NotFound)
	{
		std::cerr << "zceSendReceiveDataMain : CosNaming::NamingContext::NotFound exception while registering with the naming service." << std::endl;
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}
	ZCE_EXC_CATCHTYPE(CosNaming::NamingContext::CannotProceed)
	{
		std::cerr << "zceSendReceiveDataMain : CosNaming::NamingContext::CannotProceed exception while registering with the naming service." << std::endl;
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}
	ZCE_EXC_CATCHTYPE(CosNaming::NamingContext::InvalidName)
	{
		std::cerr << "zceSendReceiveDataMain : CosNaming::NamingContext::InvalidName exception while registering with the naming service." << std::endl;
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}
	ZCE_EXC_CATCHTYPE(CosNaming::NamingContext::AlreadyBound)
	{
		std::cerr << "zceSendReceiveDataMain : CosNaming::NamingContext::AlreadyBound exception while registering with the naming service." << std::endl;
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}
	ZCE_EXC_CATCHTYPE(CosNaming::NamingContext::NotEmpty)
	{
		std::cerr << "zceSendReceiveDataMain : CosNaming::NamingContext::NotEmpty while registering with the naming service." << std::endl;
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}
	ZCE_EXC_CATCHTYPE(CORBA::SystemException)
	{
		std::cerr << "zceSendReceiveDataMain : CORBA::SystemException while registering with the naming service." << std::endl;
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}
	ZCE_EXC_CATCHTYPE(CORBA::Exception)
 	{
		std::cerr << "zceSendReceiveDataMain : CORBA::Exception while registering with the naming service." << std::endl;
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}
	ZCE_EXC_CATCHANY
	{
		std::cerr << "zceSendReceiveDataMain : Unknown exception while registering with the naming service." << std::endl;
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}
	ZCE_EXC_ENDTRY(1)

	ZCE_EXC_TRY
	{
		if (startorb) 
		{
			orb->run(ZCE_EXC_ENV_SINGLE_PARAM);
		}
	}
	ZCE_EXC_CATCHTYPE(CORBA::SystemException) 
	{
		std::cerr << "zceSendReceiveDataMain : CORBA::SystemException during orb->run()." << std::endl;
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}
	ZCE_EXC_CATCHTYPE(CORBA::Exception)
 	{
		std::cerr << "zceSendReceiveDataMain : CORBA::Exception during orb->run()." << std::endl;
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}
	ZCE_EXC_CATCHANY
	{
		std::cerr << "zceSendReceiveDataMain : Unknown exception during orb->run()." << std::endl;
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}
	ZCE_EXC_ENDTRY(1)

	ZCE_EXC_TRY
	{
		if (startorb) 
		{
			orb->destroy(ZCE_EXC_ENV_SINGLE_PARAM);
		}
	}
	ZCE_EXC_CATCHANY
	{
		std::cerr << "zceSendReceiveDataMain : Unknown exception during orb->destroy()." << std::endl;
		_status = ZCE_STATUS_FINISHED;
		return 1;
	}
	ZCE_EXC_ENDTRY(1)

	_status = ZCE_STATUS_FINISHED;
	return 0;
}

// End-Of-File
//------------------------------------------------------------------------------
