#include <BadMagic.h>
#include <cdevMessage.h>
#include <clipMagicNumber.h>
#include <xdrClass.h>

int         GlobalDone = 0;
cdevReactor GlobalReactor;

// *****************************************************************************
// * BadMagicHandler::BadMagicHandler
// *	Default constructor for the BadMagicHandler class
// *****************************************************************************
BadMagicHandler::BadMagicHandler ( void ) 
	: stream()
	{
	}

// *****************************************************************************
// * open:
// *	Established a connection with the host specified by remote_sap
// *****************************************************************************
int BadMagicHandler::open ( const cdevAddr & addr )
	{
	int result = stream.connect (addr);
	if (result != -1)
		{
		if((result = GlobalReactor.registerHandler(this, READ_MASK|WRITE_MASK|EXCEPT_MASK))==-1)
			{
			handleClose();
			}		
		}
	return result;
	}


// *****************************************************************************
// * ~BadMagicHandler:
// *	Default destructor for the BadMagicHandler object.
// *****************************************************************************
BadMagicHandler::~BadMagicHandler (void)
	{
	GlobalReactor.extractHandler(this);
	handleClose();
	}


// *****************************************************************************
// * BadMagicHandler::getHandle
// * 	Allows the caller to obtain the file identifier of the socket.
// *****************************************************************************
int BadMagicHandler::getHandle (void) const 
	{
	return stream.getHandle(); 
	}



// *****************************************************************************
// * handleClose:
// * 	Closes the stream.
// *****************************************************************************
int BadMagicHandler::handleClose (void)
	{
	stream.close();
	fprintf(stdout, "=> Closing the BadMagic handler\n");
	fflush(stdout);
	GlobalDone = 1;
	return 0;
	}


// *****************************************************************************
// * handleInput :
// *	This function is called when data is ready to be read from a connected
// *	socket.  This function will read the data from the socket, and will then
// *	submit the buffer to the ServerInterface class for processing.
// *****************************************************************************
int BadMagicHandler::handleInput (void)
	{
	char buf[1000];
	
	fprintf(stdout, "=> Receiving unwanted input\n");
	fflush(stdout);
	
	while(stream.recv(buf, 1000)>0);
	
	return 0;
	}


// *****************************************************************************
// * handleOutput :
// *	This function is called when data is ready to be transmitted to a 
// *	connected socket.  This function will read the data from the queue, 
// *	translate it to XDR, and then transmit it to the client.
// *****************************************************************************
int BadMagicHandler::handleOutput    ( void )
	{
	static int count = 0;
	
	long              length     = 72;
	long              packets    = 1;
	long              magic      = CLIP_MAGIC_NUMBER;
	char *            deviceList = "device1";
	cdevMessageBinary msg    (1, 12, 0, 100, 200, 22, 14, 1, (char **)&deviceList, (char *)"get funky"); 
	XDR_Writer        writer (2400);
	char *            msgBuf     = NULL;
	size_t            msgLen     = 0;	

	msg.streamOut(&msgBuf, &msgLen);

	count++;
	if(count==50) magic++;
	fflush (stdout);
	writer.put(magic);
	writer.put(length);
	writer.put(packets);
	writer.put(msgLen);
	writer.put((void *)msgBuf, msgLen);
	
	fprintf(stdout, "=> I have sent %i bytes...\n", stream.send(writer.buf, 80));
	fflush(stdout);
		
	if(count>=100) GlobalDone = -1;
	return GlobalDone;
	}


// *****************************************************************************
// * handleExcept :
// *	This function is called when out of band data has been received from 
// *	the server.  It will terminate the connection with the server.
// *****************************************************************************
int BadMagicHandler::handleExcept    ( void )
	{
	fprintf(stdout, "=> I have received a terminator from the server\n");
	fflush(stdout);
	stream.close();
	GlobalDone = 1;
	return -1;
	}


int main ( int argc, char ** argv)
	{
	fprintf(stdout, "\n\
=> **********************************************************************\n\
=> * This is a test of the cdevGenericServer server-side software.      *\n\
=> * This application will transmit a group of packets to the server    *\n\
=> * and will then transmit a packet with a bad magic number.  The      *\n\
=> * should immediately terminate the client connection as soon as the  *\n\
=> * packet with the invalid magic number is received.                  *\n\
=> **********************************************************************\n\n");

	if(argc<3)
		{
		fprintf(stdout, "\
=> Insufficient parameters\n\
=> Format is : %s host port\n\
=> Terminating\n", argv[0]);

		exit(1);
		}
	
	BadMagicHandler handler;
	cdevInetAddr addr(atoi(argv[2]), argv[1]);	
	handler.open(addr);
	while(!GlobalDone) GlobalReactor.handleEvents();

	return 0;
	}
