//  
//  debug.cs
//  
//  Author:
//       Robert BRACCAGNI alias Gai-Luron <lfsgailuron@free.fr>
// 
//  Copyright (c) 2010 Gai-Luron
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
// 
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections;
using System.Text;
using System.Threading;
using System.IO;




namespace GLDebug
{
    public class Debug
    {
        enum debugType
        {
            DBG_LAPPER_ERR,
            DBG_INSTANCE_ERR,
            DBG_LAPPER_STARTSTOP,
            DBG_INSTANCE_STARTSTOP,
        }
        public string logDir = "";
        private static Mutex myMutex = new Mutex();
        private Hashtable debugOutput = new Hashtable();
        public bool printDateOnEachLine = true;
        public Debug(string plogDir)
        {
            logDir = plogDir;

        }
        public void AddDebugOutput( string pidOutPut, string pfile)
        {

            string fileName = logDir + "/" + pfile;
            if (!Directory.Exists( logDir ))
            {
                Directory.CreateDirectory( logDir );
            }
            debugOutput[pidOutPut] = fileName;

        }
        private void debugWrite( string pidOutput, string message, bool CRLF ){

            if( !debugOutput.Contains( pidOutput ) ){
                System.Diagnostics.Debug.Print("Unknown debug stream <" + pidOutput + "> :" + message);
                return;
            }
            string fileName = (string)debugOutput[pidOutput];
			bool mutexOwned = false;
            try
            {
                if (myMutex.WaitOne(1500, false))
                {
					mutexOwned = true;
                    FileInfo f = new FileInfo(fileName);
                    if (f.Length > LFSLapper.paramLapper.maxLogSize )
                    {
                        StreamWriter wfileStream = new StreamWriter(fileName, false);
                        wfileStream.WriteLine("RAZ on " + DateTime.Now);
                        wfileStream.Close();
                    }
                }
            }
            catch
            {
            }
            finally
            {
				if( mutexOwned )
                	myMutex.ReleaseMutex();
            }
            int retry = 0;
            bool flagExit = false;
            while (true)
            {
//                myMutex.WaitOne();
                try
                {
                    StreamWriter fileStream = new StreamWriter(fileName, true);
                    fileStream.Write(message);
                    if (CRLF)
                        fileStream.WriteLine("");
                    fileStream.Close();
                    flagExit = true;
                }
                catch {
                    retry++;
                    if (retry > 10)
                    {
                        Console.WriteLine("Error on writing on debug file " + fileName);
                        flagExit = true;
                    }
                    System.Threading.Thread.Sleep(100);
                }
                finally
                {
//                    myMutex.ReleaseMutex();
                }
                if (flagExit)
                    break;
            }
        }
        public string getFileName(string pidOutput)
        {

            if (!debugOutput.Contains(pidOutput))
            {
                System.Diagnostics.Debug.Print("Unknown debug stream <" + pidOutput + ">");
                return "Unknown debug stream <" + pidOutput + ">";
            }
            return (string)debugOutput[pidOutput];
        }

        public void WriteSeparator( string pidOutPut )
        {
            debugWrite(pidOutPut, "-----------------------------------------------------------------------------", true);
        }
        public void WriteDate(string pidOutPut)
        {
            debugWrite(pidOutPut, DateTime.Now + " -> ", false);
        }
        public void WriteLineDate(string pidOutPut)
        {
            debugWrite(pidOutPut, DateTime.Now.ToString(), true);
        }
        public void WriteLine(string pidOutPut, string message)
        {
            if( printDateOnEachLine )
                WriteDate(pidOutPut);
            debugWrite(pidOutPut, message, true);
        }
        public void Write(string pidOutPut, string message)
        {
            if (printDateOnEachLine)
                WriteDate(pidOutPut);
            debugWrite(pidOutPut, message, false);
        }

    }
}
