/*******************************************************************************
 * Copyright (c) 2005, 2009 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
 *
 * $Id: RACSupport.h,v 1.8 2009/08/26 14:59:57 jwest Exp $
 *
 *******************************************************************************/ 

#ifndef __RACSUPPORT_H__
#define __RACSUPPORT_H__

/* These are taken from the RAC code, but modified to remove function declarations */
#include "tptp/compatibility/RAComm.h"
#include "tptp/compatibility/RACTypes.h"


/** MALLOC  ********************************************************************
  * Localized malloc to ensure the same heap is used for all allocations and
  * deletions. (Added to RACSupport.h for Z/OS port, however, this addresses an issue that could be faced by all platforms)
  */
extern void* ra_malloc(unsigned int blockSize);

/** CRITICAL_SECTION_CREATE  ***************************************************
  * Create a critical section.
  *
  * The mutex is non-reentrant: a thread will block if it has already
  * entered the mutex and tries to enter it again.
  *
  * A thread must enter the mutex once in order to own it.
  * 
  * When ra_mutexCreate returns, no thread owns the mutex.
  */
extern void ra_mutexCreate(ra_critsec_t *lock);

/** CRITICAL_SECTION_ENTER  ***********************************************************
  * Enter a previously created critical section on this thread.
  */
extern void ra_mutexEnter(ra_critsec_t *lock);

/** CRITICAL_SECTION_EXIT  ************************************************************
  * Exit a previously entered critical section on this thread.
  */
extern void ra_mutexExit(ra_critsec_t *lock);

/** CRITICAL_SECTION_DESTROY  *********************************************************
  * Destroy a critical section.
  */
extern void ra_mutexDestroy(ra_critsec_t *lock);


/** DETERMINE_MESSAGE_LENGTH  ***************************************************
  * Determines the size buffer required to fit the information that is stored in
  * the specified ra_message_t structure.
  * @param  message - the message to determine the length of.
  * @returns     >0 - the size of buffser required.
  *               0 - the message parameter was NULL
  */
extern int ra_determineMessageLength(ra_message_t *message);

/** WRITE_MESSAGE_TO_BUFFER  **************************************************
  * Walks the data structure associted with a message and formats this into a
  * buffer that can then be transfered over a TCP connection.
  * @param       buffer - the previously allocated buffer to copy the message data to.
  * @param bufferLength - the length of the buffer.
  * @param      message - the message data structure to extract the data from.
  * @returns         >0 - the length of the buffer used for the message.
  *                  <0 - buffer is not large enough.
  */
extern unsigned int ra_writeMessageToBuffer(unsigned char *buffer,
											unsigned int bufferLength,
											ra_message_t *message);

/** READ_MESSAGE_FROM_BUFFER  *************************************************
  * Read a buffer and create a message_t data structure with all the information
  * contained in the buffer.  Use ra_destroyMessage() to free the associated memory
  * for the message_t structure when finished with it.
  * @param        buffer - the buffer with the data for the message.
  * @param messageLength - the length of the buffer containing the message data.
  * @returns       !NULL - the address of the message created.
  *                 NULL - invalid message data.
  */
extern ra_message_t* ra_readMessageFromBuffer(unsigned char *buffer,
											  unsigned long messageLength);


/** CREATE_MESSAGE  ***********************************************************
  * Allocates the memory for a message and loads it with the specified type and
  * ticket.  In order to free the memory used for this message use ra_destroyMessage()
  * @param  type  - the type of message, be it an RA_ACKNOWLEDGEMENT_MESSAGE
  *                 or a RA_CONTROL_MESSAGE.
  * @param ticket - the ticket number for this message. If this is an
  *                 RA_ACKNOWLEDGEMENT_MESSAGE this should be the ticket of the
  *                 corresponding RA_CONTROL_MESSAGE.
  * @returns !NULL - the address of the newly allocated message.
  *           NULL - inappropriate message type.
  */
extern ra_message_t* ra_createMessage(ra_uint_t type,
									  ra_uint_t ticket);


/** DESTROY_MESSAGE  **********************************************************
  * Free's all the memory currenltly held by a message and it's associated commands.
  * @param  message - the message to free all the memory of.
  * @param deepFree - Control messages consist of a list of ra_command_t stuctures
  *                   that are maintained within containers, if deepFree is true,
  *                   the actual commands are deleted along with the containers.  If
  *                   deepFree is false, only the containers are deleted.  This is
  *                   usefull for occasions when commands are copied from one message
  *                   to another without a depp copy.
  */
extern void ra_destroyMessage(ra_message_t *message,
							  BOOL deepFree);


/** ADD_COMMAND_TO_MESSAGE  ***************************************************
  * Adds a command to the message command list.
  * @param  message - the previously allocated message to append the command to.
  * @param  command - the command to append to the message command list.  If this
  *                   is NULL, the memory for the command is allocated.
  * @retruns        - a pointer to the appended command.
  */
extern ra_command_t* ra_addCommandToMessage(ra_message_t *message,
											ra_command_t *command);


/** GET_APPLICATION_LIST *****************************************
  * Retrieves the global application list for the server. The 
  * application list is all the applications that were defined in 
  * the configuration for the server and the data that was associated
  * with the applications.
  */
//extern agentControllerConfiguration_t* ra_getApplicationModel();

/** COPY_RASTRING  **************************************************************
  * Creates a copy of the source ra_string_t to the destination ar_string_t.  This
  * does not free any memory currently associated with the destination ra_string_t
  * data portion.
  * @param	destination - the ra_string_t to copy the source data to.
  * @param       source - the source ra_string_t structure.
  */
extern void ra_copyRASTRING(ra_string_t* destination, const ra_string_t* source);


/** CREATE_RASTRING  ************************************************************
  * Creates an ra_string_t from a null terminated array of characters.  This does
  * a complete copy of the stringBuffer.
  * @param    newString - the address of a ra_string_t structure to load.
  * @param stringBuffer - null terminated buffer of characters to copy into the
  *                       ra_string_t structure.
  */
extern void ra_createRASTRING(ra_string_t *newString,
							  const char *stringBuffer);

/** CREATE_RASTRING2  ***********************************************************
  * Creates an ra_string_t structure from a character buffer.  The data portion
  * of the string is a duplicate of that which is contained in the stringBuffer.
  * (Added to RACSupport.h for Z/OS port, however, this addresses an issue that could be faced by all platforms)
  * @param stringBuffer - address of a null terminated buffer of octets that
  *                       constitutes the data that wii be copied into the new
  *                       ra_string_t structure.
  */
extern ra_string_t* ra_createRASTRING2(const char *stringBuffer);

/** CREATE_RASTRING3  ************************************************************
  * Creates an ra_string_t from an array of characters.  This does
  * a complete copy of the stringBuffer for length characters.
  * @param    newString - the address of a ra_string_t structure to load.
  * @param stringBuffer - null terminated buffer of characters to copy into the
  *                       ra_string_t structure.
  * @param       length - the number of octets to copy into the string.
  */
extern void ra_createRASTRING3(ra_string_t *newString,
							  const char *stringBuffer,
							  unsigned long length);

/** CREATE_RASTRING4  ***********************************************************
  * Creates an ra_string_t structure from a character buffer.  The data portion
  * of the string is a duplicate of that which is contained in the stringBuffer.
  * (Added to RACSupport.h for Z/OS port, however, this addresses an issue that could be faced by all platforms)
  * @param stringBuffer - address of a buffer of octets that
  *                       constitutes the data that wii be copied into the new
  *                       ra_string_t structure.
  * @param       length - the number of octets to copy into the string.
  */
extern ra_string_t* ra_createRASTRING4(const char *stringBuffer,
									   unsigned long length);

/** DESTROY_RASTRING  **************************************************************
  * free any memory currently associated with the destination ra_string_t
  * data portion.
  * @param	ra_string_t to destroy.
  */
extern void ra_destroyRASTRING(ra_string_t *rastring);

/** GENERATE_UUID  ************************************************
  * Creates an ra_string_t containing a UUID.
  * @param  uuid - the address of the ra_string_t to load the UUID into.
  */
extern void ra_generateUUID(ra_string_t *uuid);

/*
 * This function return the environment variable (see also java.c)
 *
 */
int ra_getEnvironmentVariable(char* name, char* buffer, int size);


/** CLONE_COMMAND **************************************************************
  * Unlike the other functions in this file, this didn't come directly from the 
  * RAC.  This function makes a copy of a command, allocating memory as necessary
  * so that the original message can be freed with a deep free.
  *
  * @param       src - the ra_command_t to be copied
  */
extern ra_command_t* ra_cloneCommand( ra_command_t* src );

#endif /* __RACSUPPORT_H__ */
