/**********************************************************************
 * Copyright (c) 2005, 2007 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: print.h,v 1.2 2007/04/06 00:50:02 jkubasta Exp $
 * 
 * Contributors: 
 * IBM - Initial API and implementation
 **********************************************************************/

#ifndef __PRINT_H__
#define __PRINT_H__ 1

#include "RAComm.h"
#include <jvmpi.h>
#include "hash.h"
#include "stack.h"
#include "filters.h"
#include "performance.h"
#include "JvmpiWriter.h"
#include "RABindings.h"

/* TYPES
 */
#ifdef _WIN32									/* _WIN32 */
 #define TIMEB  struct _timeb
 #define FTIME(param)  _ftime(param)
 typedef unsigned __int64 Uint64;
#else											/* else */
 #define TIMEB	struct timeb
 #define FTIME(param)  ftime(param)
#endif											/* endif */

enum FieldType {Static, Instance};                    /* Indicates whether a field is a static field or an object instance field */
typedef enum FieldType FieldType_t;

/* GLOBALS
 */
extern RA_HANDLE _jvmpiAgent_outFile;
extern int    _jvmpiAgent_suspendIO;         /* TRUE = suspend output, FALSE = produce output */

/** INITIALIZE_STANDALONE_IO  **************************************************
  * Must be called when tracing in standalone mode to create IO buffers and
  * asynchronous IO support (if enabled).
  */
void jvmpiAgent_initializeStandaloneIO();


/** CLEANUP_STANDALONE_IO  *****************************************************
  * Must be called when tracing in standalone to flush/close all the IO buffers.
  */
void jvmpiAgent_cleanupStandaloneIO();


/** PRINT  ********************************************************************
  * Transmit/print the raw data to the median.
  * @param  buffer - the buffer to write to the median.
  * @param  length - number of bytes to write
  */
void jvmpiAgent_print(ThreadPrivateStorage *tps,
					  char *buffer,
					  unsigned short length);


/** PRINT_CLASS  **************************************************************
  * Handles the output of the CLASS_LOAD element and attributes
  */
void jvmpiAgent_printClass(HashEntry *classHashEntry,
						   ThreadPrivateStorage *tps);


/** PRINT_FIELDS  *************************************************************
  * Handles the output of all the STATIC_FIELD or INSTANCE_FIELD elements
  * and attributes for a class.
  */
void jvmpiAgent_printFields(ThreadPrivateStorage *tps,
							PI_Field *fp,
							int count,
							FieldType_t fieldType);


/** PRINT_METHODS  ************************************************************
  *  Handles the output of all the METHOD elements and attributes for a class.
  */
void jvmpiAgent_printMethods(HashEntry **mp,
							 int count,
							 ThreadPrivateStorage *tps);


/** PRINT_METHOD  *************************************************************
  */
void jvmpiAgent_printMethod(MethodEntry *methodEntry,
							ThreadPrivateStorage *buffer);

/** PRINT_METHOD_ENTRY_EVENT  *************************************************
  *
  */
void jvmpiAgent_printMethodEntryEvent(JVMPI_Event *event,
									  ThreadLocalStorage *tps,
									  StackEntry *se,
									  unsigned long stackDepth);


/** PRINT_METHOD_EXIT_EVENT  **************************************************
  *
  */
void jvmpiAgent_printMethodExitElement(JVMPI_Event *event,
									   ThreadLocalStorage *tps,
									   HashEntry *methodHashEntry,
				       timestamp_t timestamp,
					   timestamp_t cpu_timestamp);
					   
/** PRINT_AG_METHOD_ENTRY_EVENT  **************************preAgg/135437*******
  *
  */
void jvmpiAgent_printAgMethodEntryEvent(ThreadPrivateStorage * tps, 
									   StackFrame * call);


/** PRINT_AG_METHOD_EXIT_ELEMENT  *************************preAgg/135437*******
  *
  */
void jvmpiAgent_printAgMethodExitElement(ThreadPrivateStorage * tps, 
									   StackFrame * call);


/** PRINT_EXCEPTION_ELEMENT  **************************************************
  *
  */
void jvmpiAgent_printExceptionElement(JNIEnv *env,
									  ThreadLocalStorage *tps,
									  enum ThrowOrCatch type,
									  HashEntry *methodHashEntry,
									  jobjectID objId,
									  jthrowable e);

/** PRINT_LINE_ELEMENT  *******************************************************
  *
  */
void jvmpiAgent_printLineElement(JNIEnv *env,
								 ThreadLocalStorage *tps,
								 HashEntry *methodHashEntry,
								 unsigned short lineNumber);


/** PRINT_THREAD_END_ELEMENT  *************************************************
  */
void jvmpiAgent_printThreadEndElement(JNIEnv *env_id,
									  ThreadLocalStorage *tps);

/** PRINT_OBJ_MOVE_ELEMENT  ***************************************************
  * Handles the output of OBJ_MOVE.
  */
void jvmpiAgent_printObjMoveElement(JVMPI_Event *event,
									HashEntry *objectHashEntry);

/** PRINT_OBJ_FREE_ELEMENT  ***************************************************
  * Handles the output of OBJ_FREE.
  */
void jvmpiAgent_printObjFreeElement(ThreadLocalStorage *tps,
									HashEntry *objectHashEntry);


/** PRINT_CLASS_UNLOAD_ELEMENT  ***********************************************
  *
  * PRECONDITIONS:  classHashEntry must be valid.
  */
void jvmpiAgent_printClassUnloadElement(JVMPI_Event *event,
										ThreadLocalStorage *tps,
										HashEntry *classHashEntry);


void jvmpiAgent_printJvmInitDoneElement(JVMPI_Event *event);
void jvmpiAgent_printJvmShutdownElement(JVMPI_Event *event);

void jvmpiAgent_printGcStartElement(JVMPI_Event *event);
void jvmpiAgent_printGcFinishElement(JVMPI_Event *event);

/** PRINT_MONITOR_WAIT_ELEMENT  *****************************************************
  *
  * Print the <monWait> element to the trace indicating JVMPI_EVENT_MONITOR_WAIT occurred. 
  *
  * args - 
  *		objectHashEntry - the hash entry corresponding to the monitor object 
  *		event - the MONITOR_WAIT event as reported by JVMPI
  *		timestamp - when the MONITOR_WAIT event occurred
  *     isThreadSleep - 0 indicates regular monitor, 1 indicates wait occurred 
  *                     within Thread.sleep()
  */
void 
jvmpiAgent_printMonitorWaitElement(HashEntry *objectHashEntry, JVMPI_Event *event, 
								   timestamp_t timestamp, int isThreadSleep); 

/** PRINT_MONITOR_WAITED_ELEMENT  *****************************************************
  *
  * Print the <monWaited> element to the trace indicating JVMPI_EVENT_MONITOR_WAITED occurred. 
  *
  * args - 
  *     objectHashEntry - the hash entry corresponding to the monitor object 
  *		event - the MONITOR_WAITED event as reported by JVMPI
  *		timestamp - when the MONITOR_WAITED event occurred
  *     isThreadSleep - 0 indicates regular monitor, 1 indicates wait occurred 
  *                     within Thread.sleep()
  */
void 
jvmpiAgent_printMonitorWaitedElement(HashEntry *objectHashEntry, JVMPI_Event *event, 
								   timestamp_t timestamp, int isThreadSleep);


/** PRINT_MONITOR_STILL_OWNED_ELEMENT  ************************************************
  *
  * Print the <monStillOwned> element to the trace indicating
  * a thread is still owning a monitor at the moment we checked
  * It is potentially sent on JVMPI_EVENT_MONITOR_CONTENDED_ENTER
  * just before a <monContendedEnter> element where the
  * thread is the contended thread
  *
  * args -
  *		objectHashEntry - the hash entry corresponding to the monitor object
  *		event - the JVMPI_EVENT_MONITOR_CONTENDED_ENTER event as reported by JVMPI
  */
void
jvmpiAgent_printMonitorStillOwnedElement(HashEntry *objectHashEntry, JVMPI_Event *event);

/** PRINT_MONITOR_CONTENDED_ENTER_ELEMENT  ************************************************
  *
  * Print the <monContendedEnter> element to the trace indicating 
  * JVMPI_EVENT_MONITOR_CONTENDED_ENTER occurred. 
  *
  * args - 
  *		objectHashEntry - the hash entry corresponding to the monitor object
  *		event - the MONITOR_WAITED event as reported by JVMPI
  *		thread_owner - the current owner thread of the monitor object 
  *		timestamp - when the MONITOR_WAITED event occurred
  */
void
jvmpiAgent_printMonitorContendedEnterElement(HashEntry *objectHashEntry, JVMPI_Event *event, 
			unsigned long thread_owner, timestamp_t timestamp);

/** PRINT_MONITOR_CONTENDED_ENTERED_ELEMENT  ************************************************
  *
  * Print the <monContendedEntered> element to the trace indicating 
  * JVMPI_EVENT_MONITOR_CONTENDED_ENTERED occurred. 
  *
  * args - 
  *		objectHashEntry - the hash entry corresponding to the monitor object
  *		event - the MONITOR_WAITED event as reported by JVMPI
  *		timestamp - when the MONITOR_WAITED event occurred
  */
void
jvmpiAgent_printMonitorContendedEnteredElement(HashEntry *objectHashEntry, JVMPI_Event *event, 
			timestamp_t timestamp);

/** PRINT_OBJ_ALLOC_ELEMENT  **************************************************
  * Print OBJ_ALLOC to handle an object allocation.
  */
void jvmpiAgent_printObjAllocElement(HashEntry *objectHashEntry,
									 JNIEnv *env_id,
                                     timestamp_t timestamp);

/* REALLOCATE memory if the buffer size insufficient*******************************
 * Check buffer size and realloc memory to prevent 
 * buffer overflow.
 *
 */
void
jvmpiAgent_checkMemorySize(ThreadPrivateStorage *tps, 
						   int in_value,
						   unsigned short current);

/** PRINT_THREAD_START_ELEMENT  ***********************************************
  *
  */
void jvmpiAgent_printThreadStartElement(JNIEnv *env_id,
										HashEntry *threadHashEntry);

/** PRINT_FILTER  *************************************************************
  * Outputs a FILTER element
  */
void jvmpiAgent_printFilter(ThreadLocalStorage *tps,
							Filter *filter);

/** PRINT_OPTION  *************************************************************
  * Outputs an OPTION element
  */
void jvmpiAgent_PrintOption(ThreadLocalStorage *tps,
							char *key,
							char *value);

char * jvmpiAgent_formatName(char *name);

/** PRINT_TRACE_START_ELEMENT  ************************************************
  */
void jvmpiAgent_printTraceStartElement(ThreadLocalStorage *tps,
									   char *options);

/** PRINT_TRACE_STOP_ELEMENT  *************************************************
 */
void jvmpiAgent_printTraceStopElement(ThreadLocalStorage *tps);

void jvmpiAgent_printTraceEndElement(ThreadLocalStorage *tps);

/** PRINT_STANDALONE_TRACE_TAG_OPEN  ******************************************
  */
void jvmpiAgent_printStandaloneTraceTagOpen(ThreadLocalStorage *tps);

/** PRINT_STANDALONE_TRACE_TAG_CLOSE  *****************************************
  */
void jvmpiAgent_printStandaloneTraceTagClose(ThreadLocalStorage *tps);

/** PRINT_NODE_ELEMENT  *******************************************************
  */
void jvmpiAgent_printNodeElement(ThreadLocalStorage *tps);

/** PRINT_PROCESS_CREATE_ELEMENT  *********************************************
  */
void jvmpiAgent_printProcessCreateElement(ThreadLocalStorage *tps);

/** PRINT_AGENT_CREATE_ELEMENT  ***********************************************
  */
void jvmpiAgent_printAgentCreateElement(ThreadLocalStorage *tps,
										char *options);
/** PRINT_OBJECTREFERENCE_ELEMENT  ********************************************
  */
void jvmpiAgent_printObjectArrayReferenceElement(ThreadLocalStorage *tps,
												 unsigned long obj_id,
												 unsigned int index,
												 jint objRef_id,
												 unsigned int firstSeen);

void jvmpiAgent_printObjectInstanceReferenceElement(ThreadLocalStorage *tps,
													unsigned long obj_id,
													unsigned int index,
													jint objRef_id,
													unsigned int firstSeen,
													unsigned long fieldId);

void jvmpiAgent_printStaticReferenceElement(ThreadLocalStorage *tps,
											unsigned long class_id,
											unsigned int index,
											jint objRef_id,
											unsigned long fieldId);

/** PRINT_HEAP_DUMP START ELEMENT *********************************************
*/
void jvmpiAgent_printHDStartElement(ThreadLocalStorage *tps,
									char* heapDefName);

/** PRINT_AGENT_DESTROY_ELEMENT  **********************************************
  */
void jvmpiAgent_printAgentDestroyElement(ThreadLocalStorage *tps);


/** PRINT_AGENT_DESTROY_ELEMENT  **********************************************
  */
unsigned short jvmpiAgent_printTicketAttribute(SegmentedValue_t *ticket,
											   char *buffer,
											   unsigned short current);

/** PRINT_XML_START_ELEMENT  **************************************************
  * Place the standard XML file start entry in the specified buffer.
  * @param  buffer - the buffer that will be loaded with the string (beginning)
  */
void jvmpiAgent_printXMLStartElement(ThreadLocalStorage *tps);

/** PRINT_VM_SUSPEND  *********************************************************
  * Loads the memory address specified by 'buffer' with a Suspend entity including
  * timestamp.
  */
extern void jvmpiAgent_printVMSuspend(ThreadLocalStorage *tps);

/** PRINT_VM_RESUME  **********************************************************
  * Loads the memory address specified by 'buffer' with a Resume entity including
  * timestamp.
  */
extern void jvmpiAgent_printVMResume(ThreadLocalStorage *tps);


/** PRINT GC_ROOT *************************************************************
 */
void jvmpiAgent_printGcRootElement(JVMPI_Event *event, unsigned long id, char* type);


#endif
