/* --COPYRIGHT--,EPL
 *  Copyright (c) 2008 Texas Instruments 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
 * 
 *  Contributors:
 *      Texas Instruments - initial implementation
 * 
 * --/COPYRIGHT--*/
/*
 *  ======== HostEvent.java ======== 
 */
package xdc.rta;

import java.util.Arrays;
import java.util.Comparator;

/*
 *  ======== HostEvent ========
 *  This class is a host representation of a target event record.
 *  
 *  The HostEvent is intended as a generic representation of an XDC log event. 
 *  Different ILogger implementations may have different record formats on the
 *  target, but all XDC log decoders should return a HostEvent object.
 *  
 *  The HostEvent class is responsible for decoding a record's module ID into
 *  a module name, and the record's event ID into its message. To do this, the
 *  HostEvent requires a handle to an implementation of the IEventMetaData
 *  interface. See xdc.rta.IEventMetaData.
 */
public class HostEvent
{
    public static final int NUMARGS = 8;
    
    public int args[];          /* message arguments */
    public int eventId;         /* log event id */
    public int moduleId;        /* call site module */
    public long sequenceNum;    /* 32-bit sequence number */
    public long timestamp;      /* 64-bit timestamp */
    
    /* Address of the format string for Log_print records. */
    public long formatAddr;
    
    private IEventMetaData meta;
    
    /* Object file reader for retrieving strings for Log_print records. */
    private IOFReader ofReader = null;
    
    /*
     *  ======== HostEvent ========
     *  The HostEvent requires an IEventMetaData implementation to decode
     *  the record's event message.
     */
    public HostEvent(IEventMetaData meta)
    {
        this.meta = meta;
        this.ofReader = meta.getOFReader();
        
        this.eventId = 0;
        this.moduleId = 0;
        this.sequenceNum = 0;
        this.timestamp = 0;
        
        this.args = new int[NUMARGS];
    }
        
    /*
     *  ======== getFormatStr ========
     *  Retrieves the unformatted message for this event.
     *  
     *  If this is a Log_print record, the message is retrieved using an object
     *  file reader. Otherwise, the message is retrieved from the 
     *  IEventMetaData.
     */
    public String getFormatStr()
    {
        /* If this is a Log_print... */
    	if (this.eventId == 0) {
            if (ofReader != null) {
                return(ofReader.findString(this.formatAddr));
            }
            return (null);
        }

        /* Otherwise */
        return (meta.lookupEventMessage(this.eventId));
    }
    
    /*
     *  ======== getEventMsg ========
     *  Retrieves the formatted message for this event.
     */
    public String getEventMsg()
    {
      	String fmt = getFormatStr();
      	
      	/* 
      	 * If the format string cannot be found, display the record's raw data.
      	 */
      	if (fmt == null) {
      	    String result = "";
      	    int i = 0;
      	    
      	    /* If the record is a Log_print... */
      	    if (this.eventId == 0) {
      	        result += "Log_print(0x" + Long.toHexString(this.formatAddr);
      	        
      	        /* Arg 0 is the format address, so start with arg 1. */
      	        i = 1;
      	    }
      	    /* If the record is a Log_write... */
      	    else {
      	        result += "Log_write(eventId: " + this.eventId;
      	    }

      	    /* Add the arguments */
      	    for (; i < this.args.length; i++) {
                result += ", 0x" + Integer.toHexString(this.args[i]);
            }
      	    
      	    return (result + ")");
      	}
        
      	/* If we do have the format string... */
      	
        /* If this record is an event, not a Log_print... */
    	if (this.eventId != 0) {
    	    /* Format the message and return. */
            return (Formatter.doPrint(fmt, this.args, meta.getTargetArgSize()));
        }
    	/* If this record is a Log_print... */
    	else {
    	    /* 
             * Arg0 is the format string address, so create a new args
             * array that shifts all of the args to the left by one.
             */
            int[] formatArgs = new int[this.args.length - 1];
            for (int i = 1; i < this.args.length; i++) {
                formatArgs[i - 1] = this.args[i];
            }
            
            /* Format the message and return. */
            return (Formatter.doPrint(fmt, formatArgs, meta.getTargetArgSize()));
    	}
    }

    /*
     *  ======== getEventName ========
     *  Returns this record's event name.
     *  
     *  For Log_print records, this returns "xdc.runtime.Log_print".
     */
    public String getEventName()
    {
        String name;

        if (this.eventId == 0) {
            name = "xdc.runtime.Log_print";
        }
        else {
            name = meta.lookupEventName(this.eventId);
        }

        return (name);
    }

    /*
     *  ======== getModuleName ========
     *  Returns the name of the module that this record was logged from.
     */
    public String getModuleName()
    {
        return (meta.lookupModuleName(this.moduleId));
    }

    /*
     *  ======== toString ========
     *  Returns a string representation of the record.
     *    moduleName: eventName: event message
     */
    public String toString()
    {
        String result = "";
        String tmp;
        
        if ((tmp = getModuleName()) != null) {
            result += tmp + ": ";
        }
        else {
            result += "<invalid module id>: ";
        }

        if ((tmp = getEventName()) != null) {
            result += tmp + ": ";
        }
        else {
            result += "<invalid event id>: ";
        }

        result += getEventMsg();

        return (result);
    }
    
    /*
     *  ======== getRecordSize ========
     *  Returns the target size of this record.
     */
    public int getRecordSize()
    {
        return (meta.getTargetEventRecSize());
    }
    
    /*
     *  ======== sort ========
     *  Sorts an array of HostEvent records in place by sequence number.
     */
    public void sort(HostEvent[] evtArr)
    {
        if (evtArr.length != 0) {
            Arrays.sort(evtArr, evtArr[0].new CompareRecs());
        }
    }
    
    /* 
     *  ======== Comparator ========
     *  Comparator for sorting records based on sequence number.
     */
    public class CompareRecs implements Comparator<HostEvent>
    {       
        public int compare(HostEvent o1, HostEvent o2)
        {
            long seq1 = o1.sequenceNum;
            long seq2 = o2.sequenceNum; 
            
            return ((int) (seq1 - seq2));
        }
    }
}
