/**********************************************************************
 * Copyright (c) 2005, 2009 IBM Corporation and others.
 * 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
 * $Id: RABindings.h,v 1.4 2009/09/10 21:17:40 jcayne Exp $
 * 
 * Contributors: 
 * IBM - Initial API and implementation
 **********************************************************************/

#ifndef _RABINDINGS_H_
#define _RABINDINGS_H_


#include "RAComm.h"
#include "RASocket.h"

#if defined __cplusplus
extern "C" {
#endif

/*  The various log message severities. */
enum _RA_ERROR_LEVEL {RA_DEBUG, RA_INFORMATION, RA_WARNING, RA_SEVERE, RA_MAX_ERROR_LEVEL};
typedef enum _RA_ERROR_LEVEL RA_ERROR_LEVEL;


/* The default agent configuration information provided by the RAC is kept in a list */
typedef struct _agentConfigListEntry {
	ra_agentConfigEntry_t entry;
	struct _agentConfigListEntry *next;
	struct _agentConfigListEntry *previous;
}ra_agentConfigListEntry_t;

typedef struct {
	ra_agentConfigListEntry_t *head;
	ra_agentConfigListEntry_t *tail;
}ra_agentConfigList_t;


/* A handle for an agent that is used to hang all the agents information off of. */
typedef struct {
	BOOL finalized;
	BOOL registered;
	RA_HANDLE pipefd;
	TID    tid;
	ra_commandHandler_t  commandHandler;
	PID processID;
	ra_string_t agentUUID;
	ra_string_t processUUID;
	ra_string_t nodeUUID;
	ra_string_t agentType;
	ra_string_t agentName;
	ra_agentConfigList_t defaultConfiguration;
#ifdef _WIN32
	int pipeServerThreadEnded; // Bug 278655 - Whether or not the PipeServer(...) thread has terminated due to normal agent termination at the end of agent lifecycle
	HANDLE tHandle;		/* thread handle of the pipe server */ 
#endif 
}ra_agenthandle_t;

typedef ra_agenthandle_t* RA_AGENT_HANDLE;

/** INITIALIZE_BINDINGS  ***********************************************
  * Initialization routine for the agent bindings, must be called first
  * by te agent before running any of the other functions specified in this
  * header file.
  * @param       name - the name of the agent.
  * @param       type - the type of the agent
  * @param    handler - the callback routine for all incomming messages.
  * @param standalone - determines whether this agent should communicate with the RAC
  *                     if standalone is TRUE the RAC is never used.
  * @returns  the new handle that is used to manage the agent.
  */
extern RA_AGENT_HANDLE ra_initializeBindings(const char *name,
                                             const char *type,
                                             ra_commandHandler_t handler,
                                             BOOL standalone);

/** FINALIZE_BINDINGS  *********************************************************
  * Cleans up all the resources that were allocated during the agents
  * interaction with the bindings. Once this is called the handle is
  * no longer valid.
  * @param  handle - a handle returned by ra_initializeBindings.
  */
extern void ra_finalizeBindings(RA_AGENT_HANDLE handle);

/** START_LISTENER  ************************************************************
  * Start the message processor.
  * @param   handle - a handle returned by ra_initializeBindings
  * @param    block - whether to  block until the agent is successfuly
  *                   attached to a remote client.
  * @returns    NULL  call failed, call ra_getLastError() to determine failure
  *		    otherwise the address of the thread number the server message processor is
  *	                  listening on
  *
  */
extern TID *ra_startListener(RA_AGENT_HANDLE handle,
                             char block);


/** STOP_LISTENER  *************************************************************
  * Stops the message processor
  * @param  handle - a handle returned by ra_initializeBindings
  */
extern void ra_stopListener(RA_AGENT_HANDLE handle);

/** SEND_MESSAGE  **************************************************************
  * Send the message to the RAC on this node.  It will
  * then be forwarded by the server to the client.
  * @param  handle - a handle returned by ra_initializeBindings
  * @param   message - the message structure to send.
  * @returns the number of bytes sent to the RAC.
  */
extern int ra_sendMessage(RA_AGENT_HANDLE handle,
                          ra_message_t *message);

/** GET_PROCESS_ID  ************************************************************
  * Multiplatform convenience method to retrieve the current process
  * id.
  * @returns the PID of the curren process
  */
extern PID ra_getProcessId();

/** GET_NODE_UUID  *************************************************************
  * Retrieves the UUID of the node which this agent is running on.
  * Calling this function before ra_startListener has undefined
  * behaviour.
  */
extern const char* ra_getNodeUUID(RA_AGENT_HANDLE handle);

/** GET_PROCESS_ID  ************************************************************
  * Retrieves the UUID of the process which this agent is running in.
  * Calling this function before ra_startListener results in undefined
  * behaviour.
  */
extern const char* ra_getProcessUUID(RA_AGENT_HANDLE handle);

/** GET_AGENT_UUID  ************************************************************
  * Retrieves the agent's UUID.
  */
extern const char* ra_getAgentUUID(RA_AGENT_HANDLE handle);

/** GET_DEFAULT_CONFIGURATION  *************************************************
  * Retrieves a list of the options provided by the RAC as a default configuration
  * of the agent.  The configuration will only be available after the agent
  * has successfuly registered with the RAC.
  * @param  handle - a handle returned by ra_initializeBindings
  * @returns   the agent's default configuration list if the agent has registered
  *            with the RAC.  NULL otherwise.
  */
extern ra_agentConfigList_t* ra_getDefaultConfiguration(RA_AGENT_HANDLE handle);

/** GET_PROCESS_COMMAND_LINE  ******************************************
  */
extern char* ra_getProcessCommandLine();


/** LOG_ERROR_MESSAGE  **************************************************
  *
  */
extern void ra_logErrorMessage(RA_AGENT_HANDLE handle,
							   RA_ERROR_LEVEL  severity,
							   const char *messageId,
							   const char *message);

/* Bug 74367 */
extern int ra_logErrorMessage_return(RA_AGENT_HANDLE handle, RA_ERROR_LEVEL  severity, const char *messageId, const char *message);


/** REQUEST_PEER_MONITOR  ******************************************************
  * Requests a remote client to start monitoring this agent by asking the agent
  * controller to find the client currently monitoring a peer agent.
  * THIS IS NOT CURRENTLY SUPPORTED.  DO NOT USE!!!!!!!
  */
extern int ra_requestPeerMonitor(RA_AGENT_HANDLE handle, ra_ipaddr_t *peerAddress, PID peerPID, ra_string_t *peerAgent, unsigned long timeout);
extern int ra_requestPeerMonitor_p(RA_AGENT_HANDLE handle, ra_ipaddr_t *peerAddress, int port, PID peerPID, ra_string_t *peerAgent, unsigned long timeout); /* Bug 77768 */

/** REQUEST_PEER_MONITOR  ******************************************************
  * Requests a remote client to start monitoring this agent by asking the agent
  * controller to find the client currently monitoring a peer agent. The timeout
  * is currently not supported.
  */
extern int ra_requestPeerMonitor2(RA_AGENT_HANDLE handle, ra_ipaddr_t *peerAddress, ra_string_t *peerAgentUUID, unsigned long timeout);
extern int ra_requestPeerMonitor2_p(RA_AGENT_HANDLE handle, ra_ipaddr_t *peerAddress, int port, ra_string_t *peerAgentUUID, unsigned long timeout); /* Bug 77768 */


extern BOOL ra_initializeVMLock();
extern void ra_setVMLock();
extern void ra_releaseVMLock();
extern void ra_testVMLock();
extern BOOL ra_getVMLockState();

/*
 * Return the Option values specified in the config file
 */
extern void ra_getPropertyValues(RA_AGENT_HANDLE handle, char* name, char* type);

#if defined __cplusplus
}
#endif

#endif
