/*******************************************************************************
 * 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:
 *    Andy Kaylor, Intel - Initial API and Implementation
 *    Kevin O'Leary, Intel - Implementation
 *
 * $Id: CmdConv.c,v 1.6 2007/05/22 16:21:05 samwai Exp $
 *
 *******************************************************************************/ 

#include "tptp/TPTPTypes.h"
#include "tptp/TPTPSupportTypes.h"
#include "tptp/TPTPSupportUtils.h"
#include "tptp/BaseTLLog.h"
#include "tptp/compatibility/CmdConv.h"

static tptp_int32 convertCustomCommandToXML( tl_state_data_t* stateData, tptp_uint32 srcID, tptp_uint32 destID, ra_command_t* command, tptp_string** buffer );
static tptp_int32 convertBinaryCustomCommandToXML( tl_state_data_t* stateData, tptp_uint32 srcID, tptp_uint32 destID, ra_command_t* command, tptp_string** buffer );
static tptp_int32 convertSetNameValuePairCommandToXML( tl_state_data_t* stateData, tptp_uint32 srcID, tptp_uint32 destID, ra_command_t* command, tptp_string** buffer );
static tptp_int32 convertErrorStringCommandToXML( tl_state_data_t* stateData, tptp_uint32 srcID, tptp_uint32 destID, ra_command_t* command, tptp_string** buffer );


tptp_int32 convertCommandToXML( tl_state_data_t* stateData, tptp_uint32 srcID, tptp_uint32 destID, ra_command_t* command, tptp_string** buffer )
{
	tptp_int32 rc = 0;

	switch ( command->tag )
	{
		case RA_CUSTOM_COMMAND:
			rc = convertCustomCommandToXML( stateData, srcID, destID, command, buffer );
			break;

		case RA_BINARY_CUSTOM_COMMAND:
			rc = convertBinaryCustomCommandToXML( stateData, srcID, destID, command, buffer );
			break;

		case RA_SET_NAME_VALUE_PAIR:
			rc = convertSetNameValuePairCommandToXML( stateData, srcID, destID, command, buffer );
			break;

		case RA_ERROR_STRING:
			rc = convertErrorStringCommandToXML( stateData, srcID, destID, command, buffer );
			break;

		default:
			TPTP_LOG_ERROR_MSG1( stateData, "Cannot convert command to XML format: %d", command->tag );
			rc = -1;
	}

	return rc;
}

tptp_int32 convertCustomCommandToXML( tl_state_data_t* stateData, tptp_uint32 srcID, tptp_uint32 destID, ra_command_t* command, tptp_string** buffer )
{
 	char commandFormat[] = "<Cmd src=\"%ld\" dest=\"%ld\" ctxt=\"%ld\"><customCommand iid=\"org.eclipse.tptp.legacy\"><message>%s</message></customCommand></Cmd>";
	char* temp;
	int   binaryStringLength;
	int   rc;
	int   bufferLen;

	if ( buffer == NULL )
	{
		TPTP_LOG_ERROR_MSG( stateData, "Bad buffer parameter passed in to translate binary custom command." );
		return TPTP_CMD_BAD_ARG;
	}

	/* Calculate the size of buffer required */
	binaryStringLength = tptp_encodeBase64(command->info.custom_command.message.data, command->info.custom_command.message.length + 1, NULL, 0);

	/* Allocate space to hold the command */
	/* The 33 here is 3 times the number of digits that might be in three IDs */ 
	bufferLen = strlen(commandFormat) + 33 + binaryStringLength;
	*buffer = (tptp_string*)tptp_malloc( bufferLen );
	if ( *buffer == NULL )
	{
		TPTP_LOG_ERROR_MSG( stateData, "Unable to allocate memory to translate binary custom command." );
		return TPTP_SYS_NO_MEM;
	}

	/* Allocate temporary space to store the binary data */
	temp = (char*)tptp_malloc( binaryStringLength + 1);
	if ( temp == NULL )
	{
		tptp_free( *buffer );
		*buffer = NULL;
		TPTP_LOG_ERROR_MSG( stateData, "Out of memory while trying to translate binary custom command." );
		return TPTP_ERROR_OUT_OF_MEMORY;
	}

	/* Create a string equivalent of the binary data */
	rc = tptp_encodeBase64( command->info.custom_command.message.data, command->info.custom_command.message.length + 1, temp, binaryStringLength );
	if ( rc != 0 )
	{
		tptp_free( *buffer );
		*buffer = NULL;
		tptp_free( temp );
		TPTP_LOG_ERROR_MSG( stateData, "Error converting binary data to base64 while trying to translate binary custom command." );
		return -1;
	}


	/* Build the message */
	sprintf( *buffer, commandFormat, srcID, 
	                                 destID, 
	                                 command->info.custom_command.context,
	                                 temp ); 

	tptp_free( temp );

	return 0;
}

tptp_int32 convertBinaryCustomCommandToXML( tl_state_data_t* stateData, tptp_uint32 srcID, tptp_uint32 destID, ra_command_t* command, tptp_string** buffer )
{
 	char  commandFormat[] = "<Cmd src=\"%ld\" dest=\"%ld\" ctxt=\"%ld\"><binaryCustomCommand iid=\"org.eclipse.tptp.legacy\"><message>%s</message></binaryCustomCommand></Cmd>";
	char* temp;
	int   binaryStringLength;
	int   rc;
	int   bufferLen;

	if ( buffer == NULL )
	{
		TPTP_LOG_ERROR_MSG( stateData, "Bad buffer parameter passed in to translate binary custom command." );
		return TPTP_CMD_BAD_ARG;
	}

	/* Calculate the size of buffer required */
	binaryStringLength = tptp_encodeBase64(command->info.custom_command.message.data, command->info.custom_command.message.length, NULL, 0);

	/* Allocate space to hold the command */
	/* The 33 here is 3 times the number of digits that might be in three IDs */
	bufferLen = strlen(commandFormat) + 33 + binaryStringLength;
	*buffer = (tptp_string*)tptp_malloc( bufferLen );
	if ( *buffer == NULL )
	{
		TPTP_LOG_ERROR_MSG( stateData, "Unable to allocate memory to translate custom command." );
		return TPTP_SYS_NO_MEM;
	}

	/* Allocate temporary space to store the binary data */
	temp = (char*)tptp_malloc( binaryStringLength + 1);
	if ( temp == NULL )
	{
		tptp_free( *buffer );
		*buffer = NULL;
		TPTP_LOG_ERROR_MSG( stateData, "Out of memory while trying to translate binary custom command." );
		return TPTP_ERROR_OUT_OF_MEMORY;
	}

	/* Create a string equivalent of the binary data */
	rc = tptp_encodeBase64( command->info.custom_command.message.data, command->info.custom_command.message.length, temp, binaryStringLength );
	if ( rc != 0 )
	{
		tptp_free( *buffer );
		*buffer = NULL;
		tptp_free( temp );
		TPTP_LOG_ERROR_MSG( stateData, "Error converting binary data to base64 while trying to translate binary custom command." );
		return -1;
	}


	/* Build the message */
	sprintf( *buffer, commandFormat, srcID, 
	                                 destID, 
	                                 command->info.custom_command.context,
	                                 temp ); 

	tptp_free( temp );

	return 0;
}

tptp_int32 convertSetNameValuePairCommandToXML( tl_state_data_t* stateData, tptp_uint32 srcID, tptp_uint32 destID, ra_command_t* command, tptp_string** buffer )
{
 	char commandFormat[] = "<Cmd src=\"%ld\" dest=\"%ld\" ctxt=\"%ld\"><setNameValuePair iid=\"org.eclipse.tptp.legacy\"><type>%s</type><name>%s</name><value>%s</value></setNameValuePair></Cmd>";
	int   bufferLen;

	if ( buffer == NULL )
	{
		TPTP_LOG_ERROR_MSG( stateData, "Bad buffer parameter passed in to translate set name-value pair command." );
		return TPTP_CMD_BAD_ARG;
	}


	/* Allocate space to hold the command */
	/* The 33 here is 3 times the number of digits that might be in three IDs */
	bufferLen = strlen(commandFormat) + 33
		               + command->info.set_nv_pair.name.length
					   + command->info.set_nv_pair.type.length
					   + command->info.set_nv_pair.value.length;
	
	*buffer = (tptp_string*)tptp_malloc( bufferLen );
	if ( *buffer == NULL )
	{
		TPTP_LOG_ERROR_MSG( stateData, "Unable to allocate memory to translate set name-value pair command." );
		return TPTP_SYS_NO_MEM;
	}

	/* Build the message */
	sprintf( *buffer, commandFormat, srcID, 
	                                 destID, 
	                                 command->info.custom_command.context, 
	                                 command->info.set_nv_pair.type.data,
	                                 command->info.set_nv_pair.name.data,
	                                 command->info.set_nv_pair.value.data );

	return 0;
}

tptp_int32 convertErrorStringCommandToXML( tl_state_data_t* stateData, tptp_uint32 srcID, tptp_uint32 destID, ra_command_t* command, tptp_string** buffer )
{
 	char commandFormat[] = "<Cmd src=\"%ld\" dest=\"%ld\" ctxt=\"%ld\"><errorString iid=\"org.eclipse.tptp.legacy\"><severity>%ld</severity><messageId>%s</messageId><message>%s</message></errorString></Cmd>";
	char* temp1;
	char* temp2;
	int   errorMsgStrLen;
	int   errorMsgIdStrLen;
	int   rc;
	int   bufferLen;

	if ( buffer == NULL )
	{
		TPTP_LOG_ERROR_MSG( stateData, "Bad buffer parameter passed in to translate error string command." );
		return TPTP_CMD_BAD_ARG;
	}

	/* Calculate the size of buffers required */
	/* Message ID */
	errorMsgIdStrLen = tptp_encodeBase64( command->info.error_string.messageId.data, command->info.error_string.messageId.length + 1, NULL, 0 );

	/* Message text */
	errorMsgStrLen = tptp_encodeBase64( command->info.error_string.message.data, command->info.error_string.message.length + 1, NULL, 0 );

	/* Allocate space to hold the command */
	/* The 33 here is 3 times the number of digits that might be in three IDs */ 
	bufferLen = strlen(commandFormat) + 33 + 5 + errorMsgIdStrLen + errorMsgStrLen; /* 5 chars for severity */
	*buffer = (tptp_string*)tptp_malloc( bufferLen );
	if ( *buffer == NULL )
	{
		TPTP_LOG_ERROR_MSG( stateData, "Unable to allocate memory to translate error string command." );
		return TPTP_SYS_NO_MEM;
	}

	/* Allocate temporary space to store the message ID */
	temp1 = (char*)tptp_malloc( errorMsgIdStrLen + 1);
	temp2 = (char*)tptp_malloc( errorMsgStrLen + 1);

	if ( (temp1 == NULL) || (temp2 == NULL) )
	{
		tptp_free( *buffer );
		*buffer = NULL;
		TPTP_LOG_ERROR_MSG( stateData, "Out of memory while trying to translate error string command." );
		return TPTP_ERROR_OUT_OF_MEMORY;
	}

	/* Create a string equivalent of the message */
	rc = tptp_encodeBase64( command->info.error_string.messageId.data, command->info.error_string.messageId.length + 1, temp1, errorMsgIdStrLen );
	if ( rc != 0 )
	{
		tptp_free( *buffer );
		*buffer = NULL;
		tptp_free( temp1 );
		TPTP_LOG_ERROR_MSG( stateData, "Error converting binary data to base64 while trying to translate error string command." );
		return -1;
	}

	/* Create a string equivalent of the message */
	rc = tptp_encodeBase64( command->info.error_string.message.data, command->info.error_string.message.length + 1, temp2, errorMsgStrLen );
	if ( rc != 0 )
	{
		tptp_free( *buffer );
		*buffer = NULL;
		tptp_free( temp2 );
		TPTP_LOG_ERROR_MSG( stateData, "Error converting binary data to base64 while trying to translate error string command." );
		return -1;
	}


	/* Build the message */
	sprintf( *buffer, commandFormat, srcID, 
	                                 destID, 
	                                 command->info.error_string.context,
	                                 command->info.error_string.severity,
									 temp1,
									 temp2); 

	tptp_free( temp1 );
	tptp_free( temp2 );

	return 0;
}

