#if !defined (_CDEV_SERVER_TOOLS_H_)
#define _CDEV_SERVER_TOOLS_H_

#ifndef DONT_SUPPORT_CDEV_CALLS
	#include "cdevSystemEventHandler.h"
#endif

#include "cdevSessionManager.h"
#include "cdevMessage.h"
#include "rsvcClient.h"
#include "rsvcUdpClient.h"

// *****************************************************************************
// * This is the cdevSimpleTimer class.  The user specifies a function, a rate 
// * and a void * data pointer.  The ACE_Reactor will then call the function
// * each time the period of time expires.
// *****************************************************************************
class GENERIC_SERVER_API cdevSimpleTimer : public cdevEventHandler, public ErrorReporter
{
public:
	cdevSimpleTimer  ( cdevReactor & Reactor, double Rate = 1.0 );
	~cdevSimpleTimer ( void );
	virtual int     handleTimeout  (void);
	virtual int     execute        (void) = 0;
};


// *****************************************************************************
// * class cdevNameServerManager:
// *	This class will extract the list of cdev Name Servers from the 
// *	CDEV_NAME_SERVER environment variable and will create a collection
// *	of cdevNameServerHandler objects that will manage the connections
// *	to them.  These cdevNameServerHandler objects will register the 
// *	server with the name server and will send updates every five seconds.
// *	If the connection to the specific name server is lost, the 
// *	cdevNameServer handler will call the unregisterHandler method to 
// *	terminate the connection and before being deleted.  This object
// *	will then attempt to reestablish the connection periodically.
// *****************************************************************************
class GENERIC_SERVER_API cdevNameServerManager : public cdevEventHandler, public ErrorReporter
{
protected:
	char                        ** nameServerList;
	class cdevNameServerHandler ** nameServerHandlers;
	size_t                         nameServerCnt;
	rsvcData                       serverInfo;
	rsvcData                       updateInfo;
	char *                         serverName;
	char *                         domainName;
	unsigned short                 serverPort;
		
public:
	cdevNameServerManager     ( cdevReactor & Reactor, char * DomainName, char * ServerName, unsigned short port);
	~cdevNameServerManager    ( void );

	static void   rsvcCallback      (int status, void* arg, rsvcData* data);

	virtual int   handleTimeout     ( void );
	void          unregisterHandler ( size_t index );
	rsvcData    * getServerInfo     ( void ) { return &serverInfo; }
	rsvcData    * getUpdateInfo     ( void ) { return &updateInfo; }
	char        * getHostName       ( size_t index ) { return (index<nameServerCnt)?nameServerList[index]:(char *)"UNKNOWN"; }
};
	

// *****************************************************************************
// * class cdevNameServerHandler :
// *	This class will establish a connection with a specific cdev Name
// *	Server and will send period updates to let the name server know that 
// *	the process is still alive and operational.  If the handler loses its
// *	connection to the name server, it will notify the cdevNameServerManager
// *	prior to being deleted.  The cdevNameServer manager will then attempt
// *	to recreate the connection at a later time.
// *****************************************************************************
class GENERIC_SERVER_API cdevNameServerHandler : public cdevEventHandler, public ErrorReporter
{
protected:
	int                     nameServerIndex;
	rsvcClient            * nameServerTCP;
	rsvcUdpClient         * nameServerUDP;
	cdevNameServerManager & nameServerManager;	

public:
	cdevNameServerHandler     ( cdevNameServerManager & Manager, cdevReactor & Reactor, int index, rsvcClient *tcp, rsvcUdpClient *udp );
	~cdevNameServerHandler    ( void );
	virtual int handleInput   ( void );
	virtual int handleOutput  ( void );
	virtual int handleTimeout ( void );	
	virtual int getHandle     ( void ) const;
};


#ifndef DONT_SUPPORT_CDEV_CALLS
	// *********************************************************************
	// * class cdevSystemHandler:
	// *	This class causes the specified cdevReactor to periodically 
	// *	poll the cdevSystem for activity (by default 5 times per second).
	// *********************************************************************
	class GENERIC_SERVER_API cdevSystemHandler : public cdevSimpleTimer
	{
	protected:
		cdevSystem & system;
		
	public:
		cdevSystemHandler (cdevReactor & Reactor, 
				   double pollRate = 0.2, 
				   cdevSystem & System = cdevSystem::defaultSystem());
		virtual ~cdevSystemHandler ( void );
		int         execute        ( void );
	};
#endif

#endif  /* _CDEV_SERVER_TOOLS_H_ */
