using System;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
using System.Threading;
using Wayne.Lib;
using Wayne.Lib.Log;


namespace Wayne.ForecourtControl.Fusion
{
    //public delegate void EventHandler<ConnectionChangedEventArgs>(Object sender, EventArgs e);

    public static class Trace
    {

        public static DebugLogger debugLogger = null;
        public static SSTrace sstrace;

        public static void Add(IIdentifiableEntity logclass)
        {
            try
            {                
                string sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "Trace", "FControlFUSION");
                if (sValue != "")
                {
                    sstrace = new SSTrace(string.Format("{0}{1}", ConfigurationParams.getSINPPath("trace\\"), sValue));
                }
                else if (debugLogger == null)
                    debugLogger = new DebugLogger(logclass, true);

            }
            catch (Exception ex)
            {

            }
        }
        public static void WriteLine(string msg)
        {

            try
            {
#if (_NUCLEUS_COMPATIBLE || WindowsCE)
                if (debugLogger != null && debugLogger.IsActive())
                {
                    //string methodName = System.Reflection.MethodBase.GetMethodFromHandle().Name;
                    debugLogger.Add(msg);
                }
                if (sstrace != null)
                    sstrace.WriteLine(msg);
#else
                System.Diagnostics.Trace.WriteLine(msg);
                if (debugLogger != null && debugLogger.IsActive())
                {
                    //string methodName = System.Reflection.MethodBase.GetMethodFromHandle().Name;
                    debugLogger.Add(msg);
                }
#endif
            }
            catch (Exception ex)
            {

            }
        }

        public static void WriteLineIf(bool condition, string msg)
        {

            try
            {
#if (_NUCLEUS_COMPATIBLE || WindowsCE)
                if (debugLogger != null && debugLogger.IsActive() && (condition || debugLogger.GetDebugLevel() == DebugLogLevel.Detailed))
                {
                    //string methodName = System.Reflection.MethodBase.GetMethodFromHandle().Name;
                    debugLogger.Add(msg);

                }
                if (sstrace != null && condition)
                    sstrace.WriteLine(msg);
#else
                System.Diagnostics.Trace.WriteLineIf(condition, msg);
#endif
            }
            catch (Exception ex)
            {

            }
        }

        public static bool CheckTraceLevel(int iLevel)
        {
            int TraceLevel = 0;
            try
            {
                string sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "Trace", "TraceLevel");
                if (sValue != "")
                {
                    TraceLevel = Convert.ToInt32(sValue);
                }
                else
                {
                    sValue = IniFile.IniReadValue(ConfigurationParams.getSINPPath("ini\\") + @"Common.ini", "Trace", "TraceLevel");
                    if (sValue != "")
                    {
                        TraceLevel = Convert.ToInt32(sValue);
                    }
                }
            }
            catch (Exception ex)
            {
                TraceLevel = 0;
            }
            if (iLevel <= TraceLevel)
                return true;
            return false;
        }

    }

    public class SSTrace
    {
        private FileStream fs;
        private StreamWriter sw;

        private string strFileTrace;
        public string FileTrace
        {
            get { return strFileTrace; }
            set { strFileTrace = value; }
        }

        private string strFullFileTrace;
        public string FullFileTrace
        {
            get { return strFullFileTrace; }
            set { strFullFileTrace = value; }
        }

        private int MaxDaysTrace = 0;
        private int NewDay = -1;
        private int fileSize = 24;

        public SSTrace(string sFileTrace)
        {
            FileTrace = sFileTrace;
            NewDay = DateTime.Now.Day;
            try
            {
                string sValue;
                sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "Trace", "Size");
                if (sValue != "")
                {
                    fileSize = Convert.ToInt32(sValue);
                }
            }
            catch (Exception ex)
            {
                fileSize = 24;
            }
        }

        public void PreparaStream()
        {
            if (fs != null)
            {
                fs.Close();
            }

            fs = new FileStream(FullFileTrace, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);

            sw = new StreamWriter(fs, System.Text.Encoding.GetEncoding(1252));
            sw.AutoFlush = true;
            //Writer = sw;
        }

        public void ChiudiStream()
        {
            if (fs != null)
            {
                fs.Close();
            }
        }

        public void WriteLine(string strTrace)
        {
            if (FileTrace.Length == 0)
            {
                return;
            }

            lock(this);
            try
            {
                string strLineTrace;
                strLineTrace = string.Format("{0}: {1}", DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.ffff"), strTrace);

                bool bNuovoFile = false;
                if (FullFileTrace == null)
                {
                    DateTime now = DateTime.Now;
                    FullFileTrace = string.Format("{0}\\{1:00}-{2:00}-{3}", Path.GetDirectoryName(FileTrace), now.Day, now.Month, Path.GetFileName(FileTrace));
                }
                FileInfo fi = new FileInfo(FullFileTrace);
                if (fi.Exists && fi.Length >= System.Math.Pow(2, fileSize))
                {
                    fi.MoveTo(FullFileTrace + DateTime.Now.ToString("HH:mm:ss") + ".bck");
                    bNuovoFile = true;
                }
                if (FullFileTrace == null || !File.Exists(FullFileTrace) || bNuovoFile)
                {
                    bNuovoFile = true;
                    DateTime now = DateTime.Now;
                    FullFileTrace = string.Format("{0}\\{1:00}-{2:00}-{3}", Path.GetDirectoryName(FileTrace), now.Day, now.Month, Path.GetFileName(FileTrace));
                }

                PreparaStream();

                sw.WriteLine(strLineTrace);
                sw.Flush();

                ChiudiStream();

                CheckOldFiles();
            }
            catch (Exception ex)
            {
                ChiudiStream();
            }
            finally
            {
                
            }
        }

        public void CheckOldFiles()
		{
			if (NewDay != DateTime.Now.Day)
			{
                NewDay = DateTime.Now.Day;
				Thread th = new Thread(new ThreadStart(this.RemoveOldFiles));
				th.Start();
			}
		}

		private void RemoveOldFiles()
		{
            try
            {
                string sValue;
                sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "Trace", "MaxDaysTrace");
                if (sValue != "")
                {
                    MaxDaysTrace = Convert.ToInt32(sValue);
                }
                else
                {
                    sValue = IniFile.IniReadValue(ConfigurationParams.getSINPPath("ini\\") + @"Common.ini", "Trace", "MaxDaysTrace");
                    if (sValue != "")
                    {
                        MaxDaysTrace = Convert.ToInt32(sValue);
                    }
                }
            }
            catch (Exception ex)
            {
                MaxDaysTrace = 5;
            }

			if (MaxDaysTrace < 0)
			{
				return;
			}

			TimeSpan tsDays;
			try 
			{
                string strFilesTrace = Path.GetFileName(FileTrace) + "*.bck";
                WriteLine(string.Format("check deleting files: {0}, MaxDaysTrace={1}", strFilesTrace, MaxDaysTrace));
                DirectoryInfo di = new DirectoryInfo(ConfigurationParams.tracePath);
				// Print out the names of the files in the current directory.
				foreach (FileInfo fi in di.GetFiles(strFilesTrace))
				{
					tsDays = DateTime.Now - fi.CreationTime;
					if (tsDays.Days >= MaxDaysTrace)
					{
                        WriteLine(string.Format("tsDays.Days={0}, Deleting file: {1}", tsDays.Days, fi.Name));
						fi.Delete();
						WriteLine(string.Format("Deleted file: {0}", fi.Name));
					}
				}
			}
			catch (Exception ex)
			{

			}
		}

    }

    public static class IniFile
    {
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileSection(string section, IntPtr retVal, int size, string filePath);


        public static string IniReadValue(string Path, string Section, string Key)
        {
            StringBuilder temp = new StringBuilder(255);
            int i = GetPrivateProfileString(Section, Key, "", temp, 255, Path);
            return temp.ToString();
        }

        public static void IniWriteValue(string Path, string Section, string Key, string Value)
        {
            WritePrivateProfileString(Section, Key, Value, Path);
        }
    }
}