using System;
using System.Diagnostics;
using System.Threading;
using System.Text;
using System.Reflection;
using System.Net;
//using System.Runtime.Remoting.Messaging;

// Filename: MarketDataTrace.cs
// Author:Sean Kessler
// Date:11/2005

namespace MarketData.Utils
{
  public enum LogLevel : uint
  {
    NONE=0x0000,
    INFO=0x0002,
    DEBUG=0x0004,
    VERBOSE=0x0008
  };
/// <summary>MarketDataTrace - Utility for .</summary>
  public class MDTrace
  {
    private static LogLevel logLevel=LogLevel.DEBUG;

/// <summary>MarketDataTrace - Private constructor prevents instantiation.</summary>
/// <returns>none</returns>
    private MDTrace()
    {
    }
    
/// <summary>LogLevel - Get/Set Log level.</summary>
/// <param name="logLevel">The log level.</param>
/// <returns>LogLevel</returns>
    public static LogLevel LogLevel
    {
      get{return logLevel;}
      set{logLevel=value;}
    }
/// <summary>WriteLine - Writes a line of text to trace log.</summary>
/// <param name="message">string content of message to write.</param>
/// <returns>void</returns>
//    [Conditional("TRACE")]
    public static void Write(LogLevel logLevel,string message)
    {
      if(MDTrace.logLevel<logLevel)return;
      Trace.Write(GetCallerIP()+GetThreadRep()+GetLogLevelRep()+"["+DateTime.Now.ToString()+"]"+GetMethodInfo()+message);
      Console.Write(message);
      Flush();
    }
    
/// <summary>WriteLine - Writes a line of text to trace log.</summary>
/// <param name="message">string content of message to write.</param>
/// <returns>void</returns>
//    [Conditional("TRACE")]
    public static void WriteLine(string message)
    {
      WriteLine(LogLevel.DEBUG,GetCallerIP()+GetThreadRep()+GetLogLevelRep()+"["+DateTime.Now.ToString()+"]"+" "+GetMethodInfo()+message);
      Console.WriteLine(message);
    }
/// <summary>WriteLine - Writes a line of text to trace log.</summary>
/// <param name="message">string content of message to write.</param>
/// <returns>void</returns>
//    [Conditional("TRACE")]
    public static void WriteLine(LogLevel logLevel,Exception exception)
    {
      if(MDTrace.logLevel<logLevel)return;
      Trace.WriteLine(GetCallerIP()+GetThreadRep()+GetLogLevelRep()+"["+DateTime.Now.ToString()+"]"+" "+GetMethodInfo()+exception.ToString());
      Console.WriteLine(exception);
      Flush();
    }
/// <summary>WriteLine - Writes a line of text to trace log.</summary>
/// <param name="message">string content of message to write.</param>
/// <returns>void</returns>
//    [Conditional("TRACE")]
    public static void WriteLine(LogLevel logLevel,string message)
    {
      if(MDTrace.logLevel<logLevel)return;
      Trace.WriteLine(GetCallerIP()+GetThreadRep()+GetLogLevelRep()+"["+DateTime.Now.ToString()+"]"+" "+GetMethodInfo()+message);
      Console.WriteLine(message);
      Flush();
    }
/// <summary>Indent - set trace log indentation.</summary>
/// <returns>void</returns>
//    [Conditional("TRACE")]
    public static void Indent()
    {
      Trace.Indent();
    }
/// <summary>Unindent - set trace log indentation back.</summary>
/// <returns>void</returns>
//    [Conditional("TRACE")]
    public static void Unindent()
    {
      Trace.Unindent();
    }
/// <summary>Flush - Flush trace log buffers to disk.</summary>
/// <returns>void</returns>
//    [Conditional("TRACE")]
    public static void Flush()
    {
      Trace.Flush();
    }
/// <summary>GetLogLevel - Return current log level.</summary>
/// <returns>LogLevel</returns>
    public static LogLevel GetLogLevel(String strLogLevel)
    {
      if(strLogLevel.Equals("debug"))return LogLevel.DEBUG;
      else if(strLogLevel.Equals("verbose"))return LogLevel.VERBOSE;
      else if(strLogLevel.Equals("info"))return LogLevel.INFO;
      else return LogLevel.NONE; 
    }
    
/// <summary>GetLogLevel - Return current log level.</summary>
/// <returns>LogLevel</returns>
    private static string GetLogLevelRep()
    {
      if (MDTrace.logLevel == LogLevel.DEBUG) return "[TRACE.DEBUG]";
      else if (MDTrace.logLevel == LogLevel.VERBOSE) return "[TRACE.VERBOSE]";
      else if (MDTrace.logLevel == LogLevel.INFO) return "[TRACE.INFO]";
      else return "[TRACE.NONE]";
    }
/// <summary>GetThreadRep - Return threading information.</summary>
/// <returns>LogLevel</returns>
    private static string GetThreadRep()
    { 
      return "[Thread="+Thread.CurrentThread.GetHashCode()+"]";
    }
/// <summary>GetMethodInfo - Returns information about the calling method 2 frames up.</summary>
/// <returns>String</returns>
    private static String GetMethodInfo()
    {
      StringBuilder sb=new StringBuilder();
      StackFrame frame=new StackFrame(2,true);
	    MethodBase methodBase=frame.GetMethod();
	    ParameterInfo[] parameters=methodBase.GetParameters();
	    sb.Append("[").Append(methodBase.DeclaringType.FullName).Append("::").Append(methodBase.Name).Append("(");
	    for(int index=0;index<parameters.Length;index++)
	    {
	      ParameterInfo parameter=(ParameterInfo)parameters[index];
	      sb.Append(parameter.Name);
	      if(!(index==parameters.Length-1))sb.Append(",");
	    }
	    sb.Append(")]");
	    return sb.ToString();
    }
/// <summary>GetCallerIP - Returns the calling methods IP address.</summary>
/// <returns>String</returns>
    private static String GetCallerIP()
    {
      String hostName = Dns.GetHostName();
      String hostAddress = Dns.GetHostAddresses(hostName).ToString();
      if(null!=hostName)hostName=hostName.Split('.')[0];
      if(null==hostName && null==hostAddress)return "[LOCAL]";
      return "["+hostAddress+"->"+hostName+"]";
    }
  }
}
