/*******************************************************************************
 * Copyright (c) 2005, 2007 Intel Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Vishnu K Naikawadi, Intel - Initial implementation
 *    Andy Kaylor, Intel - Modified for sample client to make it a stress test
 *
 * $Id: FullCycle.cpp,v 1.4 2007/06/06 19:57:39 samwai Exp $
 *
 *******************************************************************************/ 


#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;

#include "tptp/client/INode.h"
#include "tptp/client/NodeFactory.h"
#include "tptp/client/Agent.h"
#include "tptp/client/Collector.h"
#include "tptp/client/Constants.h"
#include "tptp/client/IProcess.h"
#include "tptp/TPTPSupportTypes.h"
#include "TestDataProcessor.h"

#include <time.h>

using namespace TPTP::Client;

/* Test setting defaults */
int  numIterations = 500;

bool bTestSendData    = true;
bool bTestReceiveData = true;

int processCommandLineOptions( int argc, char* argv[] );

/**
 *********************************************************
 *                                                       
 * @brief                                                
 *    Test Client
 *
 *********************************************************/
int main(int argc, char* argv[])
{
	int rc = 0 ;
	char* hostName = "localhost";
	int portNum = 10006;
	INode* TestNode = 0;
	AgentController* ACProxy = 0;
	int i;
	time_t begin, end;
	double elapsed_time;
	char buffer[1024];

	rc = processCommandLineOptions( argc, argv );
	if ( rc < 0 )
		return rc;

	// Prepare the test data
	for ( i = 0; i < 1024; i++ )
	{
		buffer[i] = i/8;
	}

	//Create a Node that represents the Target Machine
	TestNode = NodeFactory::createNode(hostName);

	//Connect to the Agent Controller on that machine.
	printf( "Connecting to the Agent Controller on %s...\n\n", hostName );
	ACProxy = TestNode->connect(portNum);

	if (ACProxy == 0)
	{
		printf( "Unable to connect\n" );
		printf( "Press enter to exit...\n" );
		getchar();
		return -1;
	}

	time( &begin );

	for ( i = 0; i < numIterations; i++ )
	{
		//Get an Agent - StressAgent in this case
		Collector* stressAgent = new Collector("org.eclipse.tptp.StressAgent");
		
		printf( "\nGetting the Agent...\n" );

		int agentref = ACProxy->getAgent(stressAgent, TPTP_CONTROLLER_ACCESS | TPTP_CREATE_INSTANCE);
		if(agentref == -1)
		{
			printf( "Unable to get Agent org.eclipse.tptp.StressAgent\n" );
			printf( "Press enter to exit...\n" );
			getchar();
			return -1;
		}
		printf( "The Stress Agent ID: %d\n", stressAgent->getAgentID() );
		

		//Establish Data Path and Data Listener
		printf( "Establish the Data Channel Path with the Stress Agent...\n" );
		stressAgent->createDataConnection(TPTP_DATA_PATH_TWOWAY);
		TestDataProcessor* dataProcessor = new TestDataProcessor();
		int dataConnectionID = stressAgent->addDataListener(dataProcessor);

		if ( bTestReceiveData )
		{
			//Send RUN command - Starts the StressAgent
			printf( "R" );
			stressAgent->run();
		}

		if ( bTestSendData )
		{
			//Send Data to StressAgent		
			for(int j=0;j<100;j++)
			{
				// sent data through the path 
				int length = strlen(buffer);
				stressAgent->sendData(buffer, 100);
			}
		}
		else
		{
			Sleep( 5000 );
		}
		
		if ( bTestReceiveData )
		{
			//Send STOP command - Stops the StressAgent
			//and returns the Elapsed Time since RUN command
			//Also sends bunch of data back
			printf( "S" );
			stressAgent->stop();
		}

		// Release the time collector 
		printf( "\nReleasing the Agent...\n" );
		stressAgent->releaseAgent();
		
		delete stressAgent;
	}

	time( &end );

	elapsed_time = difftime( end, begin );
	printf( "Completed %d iterations in %.0f seconds\n", i, elapsed_time );

	ACProxy->disconnect();
	ACProxy->destroy();

	NodeFactory::deleteNode(TestNode);
		
	printf( "All finished\n" );


	printf( "Press enter to exit...\n" );
	getchar();

	return 0;
}


int processCommandLineOptions( int argc, char* argv[] )
{
	int i;

	for ( i = 1; i < argc; i++ )
	{
		if ( argv[i][0] == '-' )
		{
			switch ( argv[i][1] )
			{
				case '?':
					printf( "Usage: FullCycle [options]\n\n" );
					printf( "   -?       Show this message\n" );
					printf( "   -n<N>    Repeat the test for <N> iterations\n" );
					printf( "   -s<0|1>  Enable or disable the send data tests\n" );
					printf( "   -r<0|1>  Enable or disable the receive data tests\n" );
					return -1;
					break;

				case 'n':
					numIterations = atoi( &argv[i][2] );
					if ( numIterations == 0 )
					{
						printf( "Bad value for -n option\n\n" );
						printf( "   -n<N>  Repeat the test for <N> iterations\n" );
						printf( "          Specify a non-zero integer for <N>\n" );
						return -1;
					}
					break;

				case 's':
					if ( argv[i][2] == '0' )
					{
						bTestSendData = false;
					}
					else if ( argv[i][2] == '1' )
					{
						bTestSendData = true;
					}
					else
					{
						printf( "Bad value for -n option\n\n" );
						printf( "   -s<0|1>  Enable or disable the send data tests\n" );
						printf( "            Use either -s0 or -s1\n" );
						return -1;
					}
					break;

				case 'r':
					if ( argv[i][2] == '0' )
					{
						bTestReceiveData = false;
					}
					else if ( argv[i][2] == '1' )
					{
						bTestReceiveData = true;
					}
					else
					{
						printf( "Bad value for -n option\n\n" );
						printf( "   -r<0|1>  Enable or disable the receive data tests\n" );
						printf( "            Use either -r0 or -r1\n" );
						return -1;
					}
					break;

				default:
					break;
			}
		}
	}

	return 0;
}
