//******************************************************************************
//
// Restricted Rights
// WARNING: This is a restricted distribution Zeligsoft file.
//
//******************************************************************************
//
// Copyright (C) 2006 Zeligsoft Inc. - All Rights Reserved
//

//******************************************************************************
//
//     FILE: zceWriteDataWorker.cpp
//
//******************************************************************************

#include "zceWriteDataWorker.h"

#include "zceWriteDataPorts.h"

#include "../../Constants.h"
#include "../../Support.h"


zceWriteDataWorker::zceWriteDataWorker( const WriteData_params& execParams ZCE_EXC_ENV_ARG )
	#if defined(DEBUG_MSGS)
	 : debug_(0)
	#endif

{
	ZCE_ASSERT_EXCEPTION_VOID;
	#if defined(DEBUG_MSGS)
	debug_.rdbuf(std::cout.rdbuf());
	#endif


	initExecParams(execParams ZCE_EXC_ENV_PARAM );

	// TODO : Implement constructor for zceWriteDataWorker
}

zceWriteDataWorker::~zceWriteDataWorker()
{
	// TODO : Implement destructor for zceWriteDataWorker
}

void zceWriteDataWorker::initExecParams( const WriteData_params& params ZCE_EXC_ENV_ARG)
{

	ZCE_ASSERT_EXCEPTION_VOID;
	execParams_.NAMING_CONTEXT_IOR = params.NAMING_CONTEXT_IOR;
	execParams_.NAME_BINDING = params.NAME_BINDING;
	execParams_.COMPONENT_IDENTIFIER = params.COMPONENT_IDENTIFIER;

	// TODO: perform some action based on these exec parameters
}




/*!	\brief
 *
 *	 Describe operation here.
 *
 *	\throw ::CF::LifeCycle::InitializeError
 *
 */
void zceWriteDataWorker::CF_LifeCycle_initialize( int portIdentifier ZCE_EXC_ENV_ARG )
{
	ZCE_ASSERT_EXCEPTION_VOID;

	mIsDone=0;
	mIsStarted = 0;
	mPacketID = 0;

}

/*!	\brief
 *
 *	 Describe operation here.
 *
 *	\throw ::CF::LifeCycle::ReleaseError
 *
 */
void zceWriteDataWorker::CF_LifeCycle_releaseObject( int portIdentifier ZCE_EXC_ENV_ARG )
{
	ZCE_ASSERT_EXCEPTION_VOID;

	mIsStarted=0;
	mIsDone=1;

}

/*!
 * \brief The start operation is provided to command a Resource implementing this
 * interface to start internal processing.
 *
 * Specification reference:  3.1.3.1.6.5.2
 *
 * The start operation puts the Resource in an operating condition.
 *
 * \return This operation does not return a value.
 *
 * \throw StartError The start operation shall raise the StartError exception if
 * an error occurs while starting the resource.
 *
 */
void zceWriteDataWorker::CF_Resource_start( int portIdentifier ZCE_EXC_ENV_ARG )
{
	ZCE_ASSERT_EXCEPTION_VOID;

	mIsStarted = 1;
}

/*!
 * \brief The stop operation is provided to command a Resource implementing this
 * interface to stop internal processing.
 *
 * Specification reference:  3.1.3.1.6.5.1
 *
 * The stop operation shall disable all current operations and put the Resource in
 * a non-operating condition. Subsequent configure, query, and start operations
 * are not inhibited by the stop operation.
 *
 * \return This operation does not return a value.
 *
 * \throw StopError The stop operation shall raise the StopError exception if an
 * error occurs while stopping the resource.
 *
 */
void zceWriteDataWorker::CF_Resource_stop( int portIdentifier ZCE_EXC_ENV_ARG )
{
	ZCE_ASSERT_EXCEPTION_VOID;

	mIsStarted = 0;
}

/*!	\brief
 *
 *	 Describe operation here.
 *
 *	\param msg ( ::CF::OctetSequence )
 *
 *	\param options ( ::CF::Properties )
 *
 */
void zceWriteDataWorker::PushPorts_OctetSeqConsumer_processOctetMsg( int portIdentifier, const CF::OctetSequence& msg, const CF::Properties& options ZCE_EXC_ENV_ARG )
{
	ZCE_ASSERT_EXCEPTION_VOID;

	unsigned int propDestinationIdLength = CONST_HEADER_DESTINATION_ID_SIZE;
	unsigned int propApplicationTypeLength = CONST_HEADER_APPLICATION_TYPE_SIZE;
	unsigned int propQoSLength = CONST_HEADER_QOS_SIZE;
	unsigned int realDataLengthSizeLength = CONST_HEADER_REAL_DATA_LENGTH_SIZE;
	ostringstream destinationIdStream;
	ostringstream applicationTypeStream;
	ostringstream qosStream;
	ostringstream realDataLengthSizeStream;
	string destinationId;
	string applicationType;
	string qos;
	string realDataLengthSize;

	unsigned int headerLength = propDestinationIdLength + propApplicationTypeLength + propQoSLength + realDataLengthSizeLength;
	unsigned int processedMsgLength = msg.length() - headerLength;

	// Extract header
	CF::OctetSequence header(headerLength + 1);
	header.length(headerLength);

	int start = 0;
	int stop = header.length();

	for(unsigned int i = 0; i < header.length(); i++)
	{
		header[i] = CORBA::Octet(msg[i]);
		char chr = char(msg[i]);

		// Extract destinationId
		start = 0;
		stop = propDestinationIdLength;
		if((i >= start) && (i < stop))
		{
			destinationIdStream << chr;
		}

		// Extract applicationType
		start = propDestinationIdLength;
		stop = propDestinationIdLength + propApplicationTypeLength;
		if((i >= start) && (i < stop))
		{
			applicationTypeStream << chr;
		}

		// Extract QoS
		start = propDestinationIdLength + propApplicationTypeLength;
		stop = propDestinationIdLength + propApplicationTypeLength + propQoSLength;
		if((i >= start) && (i < stop))
		{
			qosStream << chr;
		}
		
		// Extract realDataLengthSize
		start = propDestinationIdLength + propApplicationTypeLength + propQoSLength;
		stop = propDestinationIdLength + propApplicationTypeLength + propQoSLength + realDataLengthSizeLength;
		if((i >= start) && (i < stop))
		{
			realDataLengthSizeStream << chr;
		}		
	}

	destinationId = destinationIdStream.str();
	applicationType = applicationTypeStream.str();
	qos = qosStream.str();
	realDataLengthSize = realDataLengthSizeStream.str();

	ostringstream message;
	message << destinationId << "-" << applicationType << "-" << qos << "-" << realDataLengthSize << "-\n";
	logToFile("Debug", "WriteData", message.str());

	// Extract message
	CF::OctetSequence processedMsg(processedMsgLength + 1);
	processedMsg.length(processedMsgLength);
	
	unsigned int realDataLengthSizeValue = atoi(realDataLengthSize.c_str());
	for(unsigned int i = headerLength; i < realDataLengthSizeValue; i++)
	{
		processedMsg[i - headerLength] = CORBA::Octet(msg[i]);
	}

	// Process message
	if(applicationType == "0")
	{
		// Voice
		logToFile("Debug", "WriteData", "Invalid application type\n");
	}
	else if(applicationType == "1")
	{
		// Data
		ostringstream fileName;
		fileName << destinationId << ".output";

		ofstream outFile(fileName.str().c_str(), ios_base::app);

		unsigned int realDataLengthSizeValue = atoi(realDataLengthSize.c_str());
		for(unsigned int i = headerLength; i < headerLength + realDataLengthSizeValue; i++)
		{
			outFile << msg[i];
		}

		if(outFile.is_open())
		{
			outFile.close();
		}

	}
	else
	{
		// Invalid application type
		logToFile("Debug", "WriteData", "Invalid application type\n");
	}
}


#if defined(DEBUG_MSGS)
void zceWriteDataWorker::setDebugStream(const std::ostream& stream)
{
	debug_.rdbuf(stream.rdbuf());
}

void zceWriteDataWorker::debugMsg(const std::string& msg)
{
	if(debug_ != NULL)
	{
		debug_ << msg << std::endl;
	}
}
#endif

// End-Of-File
//------------------------------------------------------------------------------
