#include <cdevReactor.h>
#include <cdevSocketAcceptor.h>
#include <cdevBufferedSocket.cc>
#include "TestNode.h"

TestNode * TestNode::freeList = NULL;

#ifndef TRUE
	#define TRUE  1
	#define FALSE 0
#endif

cdevReactor GlobalReactor;

class ServerHandler : public cdevEventHandler, public cdevNodeFactory
{	
private:
	cdevBufferedSocket stream;
	int                count;
	int                inboundCount;
		
public:
	ServerHandler ( const cdevAddr &addr )
		: count(0), inboundCount(0), stream(0, 1, this)
		{
		open(addr);
		}

	int open ( const cdevAddr & addr ) 
		{
		int retval = -1;
		
		if((retval = stream.connect(addr))==0)
			{
			retval = GlobalReactor.registerHandler(this, WRITE_MASK);
			}
		return retval;
		}

	int getHandle ( void )  const 
		{
		return stream.getHandle();
		}

	void setHandle ( int handle ) 
		{
		stream.setHandle(handle); 
		}	

	cdevStreamNode * newNode ( ssize_t size )
		{
		TestNode * node = new TestNode;
		node->setLen(size);
		return node;
		}
		
	int  handleInput ( void )
		{
		int      retval        = 0;
		cdevStreamNode * node  = NULL;
		
		if((retval = stream.receive())>0)
			{
			while((node=stream.dequeueInbound())!=NULL)
				{
				if(((inboundCount++)%1000)==0) fprintf(stdout, "CLIENT: I received \"%s\"\n", node->getBuf());
				delete node;
				}
			}

		if(retval<0) setMask(DONT_CALL);
		else if(!stream.inboundReady()) setMask(WRITE_MASK);
		
		return retval>=0?0:-1;
		}

	int handleOutput ( void )
		{
		int      retval = 0;
		
		if(!stream.outboundReady())
			{
			for(int i=0; i<1000; i++)
				{
				TestNode * node = new TestNode;
				node->setLen(sprintf(node->getBuf(), "Client Packet %i", count++)+1);
				stream.enqueueOutbound(node);
				}
			setMask(WRITE_MASK);
			}

		retval=stream.transmit();
		if(retval<0) setMask(DONT_CALL);
		else if(!stream.outboundReady()) setMask(READ_MASK);

		return retval>=0?0:-1;
		}
				
	int  handleClose ( void )
		{
		stream.close();
		return 0;
		}
};
	
int main ( int argc, char * argv[], char * envp [] )
	{
	if(argc<3)
		{
		fprintf(stderr, "%s [host] [port]\n", "ClientTest1");
		return -1;
		}

	char * host = argv[1];
	short  port = atoi(argv[2]);
	
	 

	cdevInetAddr    serverAddr( port, host);
	printf("Connecting to %s:%i\n", serverAddr.getHostName(),serverAddr.getPortNum());
	ServerHandler * client = new ServerHandler(serverAddr);

	for(int i=0; i<100; i++)
		{
		if(i%10==0) fprintf(stdout, "====> Have reached iteration %i\n", i);
		GlobalReactor.handleEvents(1.0);
		}
	return 0;
	}
