//------------------------------------------------------------------------------
// <copyright file="TraceHelper.java" company="Microsoft">
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
// <summary>
//      Helper functions for the trace.
//        (doesn't quite work, Apache CXF may be interfering)
// </summary>
//------------------------------------------------------------------------------

package com.microsoft.hpc.SOATrace;

import java.util.logging.*;

public class TraceHelper
{
    /**
     * the default event source
     */
    @SuppressWarnings("unused")
    private final static String DefaultEventSource = "HPC SOA Trace";
    
    /**
     * trace event
     * @param traceSource - the trace source
     * @param traceLevel - the trace level
     * @param format - the format string
     * @param arg1 - the parameters
     */
    public static void TraceEvent(SOATraceSource traceSource, Level traceLevel, String format, Object... arg1) 
    {
        TraceHelper.TraceString(traceSource, traceLevel, TraceHelper.CombineTraceString(format, arg1));
    }
    
    /**
     * trace error 
     * @param traceSource - the trace source
     * @param format - the format string
     * @param objparams - the parameters
     */
    public static void TraceError(SOATraceSource traceSource, String format, Object... objparams)
    {
        TraceHelper.TraceString(traceSource, Level.SEVERE, TraceHelper.CombineTraceString(format, objparams));
    }
    
    /**
     * trace warning
     * @param traceSource - the trace source
     * @param format - the format string
     * @param objparams - the parameters
     */
    public static void TraceWarning(SOATraceSource traceSource, String format, Object... objparams)
    {
        TraceHelper.TraceString(traceSource, Level.WARNING, TraceHelper.CombineTraceString(format, objparams));
    }
    
    /**
     * trace information
     * @param traceSource - the trace source
     * @param format - the format string
     * @param objparams - the parameters
     */
    public static void TraceInfo(SOATraceSource traceSource, String format, Object... objparams)
    {
        TraceHelper.TraceString(traceSource, Level.INFO, TraceHelper.CombineTraceString(format, objparams));
    }
    
    /**
     * trace verbose
     * @param traceSource - the trace source
     * @param format - the format string
     * @param objparams - the parameters
     */
    public static void TraceVerbose(SOATraceSource traceSource, String format, Object... objparams)
    {
        TraceHelper.TraceString(traceSource, Level.CONFIG, TraceHelper.CombineTraceString(format, objparams));
    }
    
    /**
     * trace the exception
     * @param traceSource - the trace source
     * @param exception - the exception
     */
    public static void TraceException(SOATraceSource traceSource, Exception exception)
    {
        TraceHelper.TraceString(traceSource, Level.SEVERE, TraceHelper.Exception2String(null, exception));
    }
    
    /**
     * trace the exception
     * @param traceSource - the trace source
     * @param description - the description for the exception 
     * @param exception - the exception 
     */
    public static void TraceException(SOATraceSource traceSource, String description, Exception exception)
    {
        TraceHelper.TraceString(traceSource, Level.SEVERE, TraceHelper.Exception2String(description, exception));
    }
    
    /**
     * trace the exception
     * @param traceSource - the trace source 
     * @param traceLevel - the trace level for the exception
     * @param exception - the exception
     */
    public static void TraceException(SOATraceSource traceSource, Level traceLevel, Exception exception)
    {
        TraceHelper.TraceString(traceSource, traceLevel, TraceHelper.Exception2String(null, exception));
    }
    
    /**
     * trace the exception
     * @param traceSource - the trace context
     * @param traceLevel - the trace level
     * @param description - the description for the exception
     * @param exception - the exception
     */
    public static void TraceException(SOATraceSource traceSource, Level traceLevel, String description, Exception exception)
    {
        TraceHelper.TraceString(traceSource, traceLevel, TraceHelper.Exception2String(description, exception));
    }
    
    /**
     * the helper function to write the trace
     * @param traceSource - the trace context
     * @param traceLevel - the trace level
     * @param content - the string content
     */
    private static void TraceString(SOATraceSource traceSource, Level traceLevel, String content)
    {
        try
        {
            String traceText = "";
            String sessionId = traceSource.getSessionId();
            if (sessionId != null && sessionId != "")
            {
                traceText += "[Session:" + sessionId + "], ";
            }
            
            traceText += content;
            //String eventSource = TraceHelper.DefaultEventSource;
            if (traceSource != null)
            {
                StackTraceElement StackClass = new Throwable().getStackTrace()[1]; //right?
                String sourceClass = StackClass.getClassName();
                String sourceMethod = StackClass.getMethodName();
                
                traceSource.getTraceSource().logp(traceLevel, sourceClass, sourceMethod, traceText);
                
                if (traceSource.getEventSource() != null && traceSource.getEventSource() != "")
                {
                    ;//eventSource = traceSource.getEventSource();
                }
            }
            
            //No way for Java to write to EventLog
        }
        catch (Exception e)
        {
            //failed to write the trace.
        }
    }
    
    /**
     * the helper function to combine the trace string
     * @param format - the format string 
     * @param objparams - the parameters
     * @return - the combined trace string
     */
    private static String CombineTraceString(String format, Object... objparams)
    {
        String traceString = null;
        try
        {
            traceString = String.format(format, objparams);
        }
        catch (Exception e)
        {
            traceString = "Fail to combine the trace string, format:" + format;
            if (objparams == null || objparams.length <= 0)
            {
                traceString += ", objparams is null";
            }
            else
            {
                traceString += ", objparams.length = " + objparams.length;
            }
            
            traceString += ", Exception: " + e.toString();
        }
        
        return traceString;
    }
    
    /**
     * the helper function to transfer the exception to string
     * @param description - the description for the trace
     * @param e - the exception 
     * @return - the string that contains the session id, description and the exception information
     */
    private static String Exception2String(String description, Exception e)
    {
        String exceptionStr = "";
        try
        {
            if( description != null && description != "")
            {
                exceptionStr += ", Description:" + description;
            }
            
            if (e != null)
            {
                exceptionStr += ", Exception:" + e.toString();
            }
            
        }
        catch (Exception ex)
        {
            //failed to transfer the exception to string.
        }
        
        return exceptionStr;
    }
    
    //private static EventLogEntryType TraceType2EntryType(TraceEventType type)
    //      Not implementable in java
    
}
