/*******************************************************************************
 * Copyright (c) 2005, 2006 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 - Converted sample to a test agent
 *
 * $Id: StressAgent.cpp,v 1.4 2006/10/26 22:01:43 kcallaghan Exp $
 *
 *******************************************************************************/ 


#include "StressAgent.h"


StressAgent::StressAgent(char* name) : BaseCollectorImpl(name), BaseAgentImpl(name)
{	
	running = false;
}


StressAgent::~StressAgent()
{
}


int StressAgent::sendPingResponse(CmdBlock* cmdBlock)
{
	int ret = -1;

	int destID = cmdBlock->getDestID();
	int sourceID = cmdBlock->getSourceID();
	int contextID = cmdBlock->getContextID();

	char   commandFormat[] = "<Cmd src=\"%ld\" dest=\"%ld\" ctxt=\"%ld\"><pingResponse iid=\"org.eclipse.tptp.StressAgent\"><data>a</data></pingResponse></Cmd>";
	char   command[1024];
	sprintf( command, commandFormat, destID, sourceID, contextID );

	ret = BaseAgentImpl::sendCommand(command);

	return ret;
}


int StressAgent::run(CmdBlock* cmdBlock)
{
	TID tid;

	printf( "R" );

	/* This needs to be revisited.  We should have an API that allows
	   us to know who wants to receive our data.  For now, we're assuming
	   that it is whoever sent us the run command. */
	dataListenerID = cmdBlock->getSourceID();

	running = true;

	/* Start the runThread */
#ifdef _WIN32
	CreateThread(NULL,                /* default security attributes       */
				 0,                   /* same stack size as current thread */
				 runThreadWin32,      /* Thread entry point                */
				 (LPVOID)this,        /* flusher info params               */
				 0,                   /* start executing immediately       */
				 &tid );              /* the thread ID                     */
#else
	pthread_create( &tid, NULL, runThreadNonWin32, (void *)this );
#endif

	sendRunResponse(cmdBlock);

	return 0;
}

int StressAgent::sendRunResponse(CmdBlock* cmdBlock)
{
	int ret = -1;

	int destID = cmdBlock->getDestID();
	int sourceID = cmdBlock->getSourceID();
	int contextID = cmdBlock->getContextID();

	char   commandFormat[] = "<Cmd src=\"%ld\" dest=\"%ld\" ctxt=\"%ld\"> <agentRunning iid=\"org.eclipse.tptp.Collector\"></agentRunning></Cmd>";
	char   command[1024];
	sprintf( command, commandFormat, destID, sourceID, contextID);

	ret = BaseAgentImpl::sendCommand(command);

	return ret;
}

int StressAgent::stop(CmdBlock* cmdBlock)
{
	printf( "S" );

	/* This will stop the run thread */
	running = false;

	sendStopResponse(cmdBlock);

	return 0;
}

int StressAgent::sendStopResponse(CmdBlock* cmdBlock)
{
	int ret = -1;

	int destID = cmdBlock->getDestID();
	int sourceID = cmdBlock->getSourceID();
	int contextID = cmdBlock->getContextID();

	char   commandFormat[] = "<Cmd src=\"%ld\" dest=\"%ld\" ctxt=\"%ld\"> <agentStopped iid=\"org.eclipse.tptp.Collector\"></agentStopped></Cmd>";
	char   command[1024];
	sprintf( command, commandFormat, destID, sourceID, contextID );

	ret = BaseAgentImpl::sendCommand(command);

	return ret;
}

/* static method */
#ifdef _WIN32
DWORD WINAPI StressAgent::runThreadWin32(LPVOID param)
#else
void *StressAgent::runThreadNonWin32(void* param)
#endif
{
	StressAgent* pThis = (StressAgent*)param;
	pThis->runThread();
	return 0;
}

void StressAgent::runThread()
{
	int  listenerID = /* TODO */0;
	int  count = 0;
	char buffer[1024];
	int  ret = -1;
	int  i;

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

	while (running)
	{
		/* send data through the path */
		ret = sendData(dataListenerID, buffer, 1000); // TODO: Figure out why this doesn't work if I don't leave 12 bytes of my buffer unused
		count++;
	}
}


int StressAgent::processCommand(CmdBlock* cmdBlock)
{

	int ret = 0;

	ret = BaseCollectorImpl::processCommand(cmdBlock);

	if (ret == 0) return ret;

	char* cmdName = cmdBlock->getCommandName();

	if ( isEqualString(cmdBlock->getIID(), "org.eclipse.tptp.StressAgent") )
	{
		if ( isEqualString(cmdName, "Ping") )
		{
			sendPingResponse(cmdBlock);
		}
	}

	return ret;
}


int StressAgent::receiveData(int sourceID, char buffer[], int bytesRead, DIME_HEADER_PTR_T dimeHeader)
{
	static int totalData = 0;

	totalData += bytesRead;
	if ( totalData > 1000000 )
	{
		printf( "M" );
		totalData = 0;
	}

	return 0;
}

int main(int argc, char* argv[])
{

	char* collectorName = "org.eclipse.tptp.StressAgent";

	StressAgent* StressAgentAgent = new StressAgent(collectorName);
	
	StressAgentAgent->processCommandLine(argc, argv);

	printf( "Registering agent...\n" );
	StressAgentAgent->registerAgent();

	printf( "Waiting for termination...\n" );
	StressAgentAgent->waitForTermination();

	delete StressAgentAgent;

	return 0;
}

