/*******************************************************************************
 * Copyright (c) 2003-2009 IBM, 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 Naikawadi Intel - Added various logging MACROS
 *    IBM - Portions of old RAC code (brought over by Vishnu Naikawadi)
 *
 * $Id: TPTPCommand.cpp,v 1.11 2009/05/20 03:35:11 kchan Exp $ 
 ******************************************************************************/ 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tptp/TPTPCommand.h"
#include <sstream>


#define BUFFER_LENGTH 1024

using namespace std;

TPTPCommand::TPTPCommand()
{
	_sourceID = -1;
	_destID = -1;
	_contextID = -1;
	_iid = NULL;
	_commandName = NULL;

	tptp_list_init(&_paramList);
	tptp_list_setNodeDestructor(&_paramList, destroyParamNode);
	tptp_list_setNodeCopier(&_paramList, copyParamNode);
}


TPTPCommand::TPTPCommand(int srcID, int destID, int contextID, char* iid, char* commandName)
{
	_sourceID = srcID;
	_destID = destID;
	_contextID = contextID;

	if (iid)
	{
		int len = strlen(iid) + 1;
		_iid = (char *) tptp_malloc(len);
		memcpy(_iid, iid, len);
	}
	else
		_iid = NULL;

	if (commandName)
	{
		int len = strlen(commandName) + 1;
		_commandName = (char *) tptp_malloc(len);
		memcpy(_commandName, commandName, len);
	}
	else
		_commandName = NULL;
	
	tptp_list_init(&_paramList);
	tptp_list_setNodeDestructor(&_paramList, destroyParamNode);
	tptp_list_setNodeCopier(&_paramList, copyParamNode);
}


TPTPCommand::~TPTPCommand()
{
	tptp_free(_commandName);
	tptp_free(_iid);
	tptp_list_clear(&_paramList);
}


void TPTPCommand::setSourceID(int srcID)
{
	_sourceID = srcID;
}


void TPTPCommand::setDestID(int destID)
{
	_destID = destID;
}


void TPTPCommand::setContextID(int contextID)
{
	_contextID = contextID;
}


void TPTPCommand::setIID(char* iid)
{
	if (_iid == iid) return;

	if (_iid) tptp_free(_iid);

	if (iid)
	{
		int len = strlen(iid) + 1;
		_iid = (char *) tptp_malloc(len);
		memcpy(_iid, iid, len);
	}
	else
		_iid = NULL;
}


void TPTPCommand::setCommandName(char* commandName)
{
	if (_commandName == commandName) return;

	if (_commandName ) tptp_free(_commandName);

	if (commandName)
	{
		int len = strlen(commandName) + 1;
		_commandName = (char *) tptp_malloc(len);
		memcpy(_commandName, commandName, len);
	}
	else
		_commandName = NULL;
}


void TPTPCommand::setParamList(tptp_list_t* newParamList)
{
	if (&_paramList == newParamList) return;

	// Clear any existing parameters and copy the new list of
	// parameters into this command.
	tptp_list_clear(&_paramList);
	tptp_list_clone(&_paramList, newParamList);
	return;
}


int TPTPCommand::getSourceID()
{
	return _sourceID;
}


int TPTPCommand::getDestID()
{
	return _destID;
}


int TPTPCommand::getContextID()
{
	return _contextID;
}


char* TPTPCommand::getIID()
{
	return _iid;
}


char* TPTPCommand::getCommandName()
{
	return _commandName;
}


tptp_list_t* TPTPCommand::getParamList()
{
	return &_paramList;
}


char* TPTPCommand::buildCommandString()
{
	/*
	char   commandFormat[] = "<Cmd src=\"%ld\" dest=\"%ld\" ctxt=\"%ld\"><%s iid=\"%s\"></%s></Cmd>";
	char   command[BUFFER_LENGTH];

	sprintf( command, commandFormat, this->_sourceID, this->_destID, this->_contextID, this->_commandName, this->_iid, this->_commandName);
	*/

	if (!isComplete()) return 0;

	std::ostringstream commandStream;	

	commandStream<<"<Cmd src=\""<<this->_sourceID<<"\" dest=\""<<this->_destID<<"\" ctxt=\""<<this->_contextID<<"\"><"<<this->_commandName<<" iid=\""<<this->_iid<<"\">";

	// Loop through the list of parameters and append the name/value pair
	tptp_node_t*  node;
	tptp_param_t* tmpParam;
	for (node = _paramList.head; node != 0; node = node->next)
	{
		tmpParam = (tptp_param_t*)node->data;
		if (!tmpParam) continue;  //empty data field, skip this node
		commandStream<<"<"<<tmpParam->name<<">"<<tmpParam->value<<"</"<<tmpParam->name<<">";
	}
	commandStream<<"</"<<this->_commandName<<"></Cmd>";

	this->_commandString = commandStream.str();

	return (char*)(_commandString.c_str());
}


char* TPTPCommand::buildCommandString(int srcID, int destID, int contextID, char* iid, char* commandName)
{
	if (!isComplete()) return 0;

	std::ostringstream commandStream;	

	commandStream<<"<Cmd src=\""<<srcID<<"\" dest=\""<<destID<<"\" ctxt=\""<<contextID<<"\"><"<<commandName<<" iid=\""<<iid<<"\"></"<<commandName<<"></Cmd>";
	this->_commandString = commandStream.str();

	return (char*)(_commandString.c_str());
}


char* TPTPCommand::buildReplyCommandString(TPTPCommand* inputCommand, char* commandName)
{
	std::ostringstream commandStream;	

	this->_commandName = commandName;
	this->_sourceID = inputCommand->getDestID();
	this->_destID = inputCommand->getSourceID();
	this->_contextID = inputCommand->getContextID();
	this->_iid = inputCommand->getIID();

	commandStream<<"<Cmd src=\""<<inputCommand->getDestID()<<"\" dest=\""<<inputCommand->getSourceID()<<"\" ctxt=\""<<inputCommand->getContextID()<<"\"><"<<commandName<<" iid=\""<<inputCommand->getIID()<<"\"></"<<commandName<<"></Cmd>";
	this->_commandString = commandStream.str();

	return (char*)(_commandString.c_str());
}


char* TPTPCommand::buildReplyCommandString(TPTPCommand* inputCommand, char* commandName, char* iid)
{
	std::ostringstream commandStream;	

	this->_commandName = commandName;
	this->_sourceID = inputCommand->getDestID();
	this->_destID = inputCommand->getSourceID();
	this->_contextID = inputCommand->getContextID();
	this->_iid = iid;

	commandStream<<"<Cmd src=\""<<inputCommand->getDestID()<<"\" dest=\""<<inputCommand->getSourceID()<<"\" ctxt=\""<<inputCommand->getContextID()<<"\"><"<<commandName<<" iid=\""<<iid<<"\"></"<<commandName<<"></Cmd>";
	this->_commandString = commandStream.str();

	return (char*)(_commandString.c_str());
}


void TPTPCommand::addIntegerParam(char* name, int value)
{
	char strValue[256];

	if (!name) return;

	sprintf(strValue, "%d\0", value);

	tptp_param_t* newParam = initParamT(name, strValue);

	tptp_list_add(&_paramList, (void *)newParam);

	return;
}

void TPTPCommand::addPIDParam(char* name, PID value)
{
	char strValue[256];

	if (!name) return;

	sprintf(strValue, "%lu\0", value);

	tptp_param_t* newParam = initParamT(name, strValue);

	tptp_list_add(&_paramList, (void *)newParam);

	return;
}


void TPTPCommand::addStringParam(char* name, char* value)
{

	if (!name) return;

	tptp_param_t* newParam = initParamT(name, value);
	tptp_list_add(&_paramList, (void *)newParam);

	return;
}

bool TPTPCommand::isComplete()
{
	if ((_commandName != NULL) || (_iid != NULL))
	{
		return true;
	}

	return false;
}



