using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace SPC.Kiosk.Common
{
    /// <summary>
    /// Common Logging Class
    /// </summary>
    public static class CommonLog
    {
        /// <summary>
        /// Info Log Write
        /// </summary>
        /// <param name="_nameSpace"></param>
        /// <param name="_className"></param>
        /// <param name="_functionName"></param>
        /// <param name="_logString"></param>
        /// <param name="_subString"></param>
        public static void InfoLogWrite(string _nameSpace, string _className, string _functionName, string _logString, string _subString = "")
        {
            try
            {
                InfoLogWrite(string.Format("{0}.{1} {2} {3}", _nameSpace, _className, _functionName, _logString), _subString);
            }
            catch
            {
            }
        }
        /// <summary>
        /// Info Log Write
        /// </summary>
        /// <param name="_sendClass"></param>
        /// <param name="_functionName"></param>
        /// <param name="_logString"></param>
        /// <param name="_subString"></param>
        public static void InfoLogWrite(object _sendClass, string _functionName, string _logString="", string _subString = "")
        {
            try
            {
                LogWrite(Log_Type.Info, _sendClass, _functionName, _logString, _subString);

            }
            catch
            {
            }
        }

        /// <summary>
        /// Info Log Write
        /// </summary>
        /// <param name="_logString"></param>
        /// <param name="_subString"></param>
        public static void InfoLogWrite(string _logString, string _subString = "")
        {
            try
            {
                LogWrite(Log_Type.Info, _logString, _subString);

            }
            catch
            {
            }
        }

        /// <summary>
        /// Error Log Write
        /// </summary>
        /// <param name="_nameSpace"></param>
        /// <param name="_className"></param>
        /// <param name="_functionName"></param>
        /// <param name="_errorLogString"></param>
        /// <param name="_errorSubString"></param>
        public static void ErrorLogWrite(string _nameSpace, string _className, string _functionName, string _errorLogString, string _errorSubString = "")
        {
            try
            {
                ErrorLogWrite(string.Format("{0}.{1} {2} {3}", _nameSpace, _className, _functionName, _errorLogString), _errorSubString);
            }
            catch
            {
            }
        }
        /// <summary>
        /// Error Log Write
        /// </summary>
        /// <param name="_sendClass"></param>
        /// <param name="_functionName"></param>
        /// <param name="_errorLogString"></param>
        /// <param name="_errorSubString"></param>
        public static void ErrorLogWrite(object _sendClass, string _functionName, string _errorLogString="", string _errorSubString = "")
        {
            try
            {
                LogWrite(Log_Type.Error, _sendClass, _functionName, _errorLogString, _errorSubString);

            }
            catch
            {
            }
        }
        /// <summary>
        /// Error Log Write
        /// </summary>
        /// <param name="_errorLogString"></param>
        /// <param name="_errorSubString"></param>
        public static void ErrorLogWrite(string _errorLogString, string _errorSubString = "")
        {
            try
            {
                LogWrite(Log_Type.Error, _errorLogString, _errorSubString);

            }
            catch
            {
            }
        }
        /// <summary>
        /// Bebug Log Write
        /// </summary>
        /// <param name="_nameSpace"></param>
        /// <param name="_className"></param>
        /// <param name="_functionName"></param>
        /// <param name="_debugLogString"></param>
        /// <param name="_debugSubString"></param>
        public static void DebugLogWrite(string _nameSpace, string _className, string _functionName, string _debugLogString, string _debugSubString = "")
        {
            try
            {
                DebugLogWrite(string.Format("{0}.{1} {2} {3}", _nameSpace, _className, _functionName, _debugLogString), _debugSubString);
            }
            catch
            {
            }
        }
        /// <summary>
        /// Bebug Log Write
        /// </summary>
        /// <param name="_sendClass"></param>
        /// <param name="_functionName"></param>
        /// <param name="_debugLogString"></param>
        /// <param name="_debugSubString"></param>
        public static void DebugLogWrite(object _sendClass, string _functionName, string _debugLogString="", string _debugSubString = "")
        {
            try
            {
                LogWrite(Log_Type.Debug, _sendClass, _functionName, _debugLogString, _debugSubString);

            }
            catch
            {
            }
        }
        /// <summary>
        /// Bebug Log Write
        /// </summary>
        /// <param name="_debugLogString"></param>
        /// <param name="_debugSubString"></param>
        public static void DebugLogWrite(string _debugLogString, string _debugSubString = "")
        {
            try
            {
                LogWrite(Log_Type.Debug, _debugLogString, _debugSubString);
            }
            catch
            {
            }
        }
        /// <summary>
        /// Log Write
        /// </summary>
        /// <param name="_logType"></param>
        /// <param name="sendClass"></param>
        /// <param name="_functionName"></param>
        /// <param name="_logString"></param>
        /// <param name="_subString"></param>
        private static void LogWrite(Log_Type _logType, object sendClass, string _functionName, string _logString, string _subString)
        {
            try
            {
                var type = sendClass.GetType();
                LogWrite(_logType, string.Format("{0}.{1} {2} {3}", type.Namespace, type.Name, _functionName, _logString), _subString);
            }
            catch
            {
                LogWrite(_logType, string.Format("{0} {1}", _functionName, _logString), _subString);
            }
        }

        /// <summary>
        /// Log Write
        /// </summary>
        /// <param name="_logType"></param>
        /// <param name="_logString"></param>
        /// <param name="_logSubString"></param>
        private static void LogWrite(Log_Type _logType, string _logString,string _logSubString)
        {
            try
            {
                using (var oLog = new logging(CommonValue.KioskLogSetting))
                {
                    oLog.LogWrite
                    (
                        new Log_Message
                        {
                            LogDate = DateTime.Now,
                            LogFrom = CommonValue.LogName,
                            LogType = _logType,
                            LogMessage = string.IsNullOrEmpty(_logString)
                                      ? _logString
                                      : string.Format("{0}\n\t{1}", _logString, _logSubString),
                        }
                    );
                }

            }
            catch
            {
            }
        }

    }

    #region Log Writer Class
    /// <summary>
    /// Log Store Object
    /// </summary>
    public class logging : IDisposable
    {
        private Log_Setting Log_CFG;        //Object Configuration Infomation
        private DateTime LastLogTime;       //Last Log Create Time
        private String _LogPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Log");
        /// <summary>
        /// Log Configuration Setting
        /// </summary>
        public Log_Setting Log_Set
        {
            get { return Log_CFG; }
            set { Log_CFG = value; }
        }
        /// <summary>
        /// logging a Message object
        /// </summary>
        /// <param name="_LogCFG"></param>
        public logging(Log_Setting _LogCFG)
        {
            Log_Set = _LogCFG;
            if (!Log_Set.LogPath.Equals(string.Empty) && !Log_Set.LogName.Equals(string.Empty))
            {
                if (Log_Set.LogPath.IndexOf('\\') > -1)
                {
                    _LogPath = Path.Combine(Log_Set.LogPath, Log_Set.LogName);
                }
                else
                {
                    _LogPath = Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Log_Set.LogPath), Log_Set.LogName);
                }
            }
            else if (!Log_Set.LogPath.Equals(string.Empty))
            {
                if (Log_Set.LogPath.IndexOf('\\') > -1)
                {
                    _LogPath = Log_Set.LogPath;
                }
                else
                {
                    _LogPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Log_Set.LogPath);
                }

            }
            else
            {
                _LogPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ".Log");
            }

            if (!Directory.Exists(_LogPath)) Directory.CreateDirectory(_LogPath);
            LastLogTime = DateTime.Now.AddDays(-1F);
        }

        public void Dispose()
        {

        }
        /// <summary>
        /// logging function
        /// </summary>
        /// <param name="_LogData">log data</param>
        public void LogWrite(Log_Message _LogData)
        {
            int retryCount = 0;
            bool result = false;
            do
            {
                result = LogWriteToFile(_LogData);
                retryCount++;
            } while (!result && retryCount < 100);
            if (!result)
            {
                Console.WriteLine(string.Format("Log Write Fail:{0}", _LogData.LogMessage));
            }
        }
        /// <summary>
        /// Log Write Internal Function
        /// </summary>
        /// <param name="_LogData"></param>
        /// <returns></returns>
        private bool LogWriteToFile(Log_Message _LogData)
        {
            bool result = false;
            try
            {
                if (Array.IndexOf(Log_Set.LogFrom, _LogData.LogFrom) > -1
                   && Array.IndexOf(Log_Set.LogType, _LogData.LogType) > -1)
                {
                    string _filePath = Path.Combine(_LogPath, string.Format("{0}_{1}.log", _LogData.LogFrom, _LogData.LogDate.ToString("yyyyMMdd")));
                    result = rTextFileWrite(string.Format("{0},{1},{2},{3}\r\n"
                                        , _LogData.LogDate.ToString("yyyy-MM-dd HH:mm:ss.fff")
                                        , _LogData.LogFrom
                                        , _LogData.LogType
                                        , _LogData.LogMessage), _filePath, true);
                    if (LastLogTime.Date != DateTime.Now.Date)
                    {
                        DateTime _chkDate = DateTime.Now.AddDays(Log_Set.LogDates * -1);
                        string[] getFiles = Directory.GetFiles(_LogPath);
                        foreach (string aFile in getFiles)
                        {
                            if (File.GetCreationTime(aFile).Date < _chkDate.Date)
                            {
                                File.Delete(aFile);
                            }
                        }
                    }
                    LastLogTime = _LogData.LogDate;
                }
                else
                {
                    result = true;
                }
            }
            catch
            {

            }
            return result;
        }
        /// <summary>
        /// String Add to File
        /// </summary>
        /// <param name="_dataString"></param>
        /// <param name="_filePath"></param>
        /// <param name="_append"></param>
        /// <returns></returns>
        public bool rTextFileWrite(string _dataString, string _filePath, bool _append)
        {
            bool result = false;
            try
            {
                using (StreamWriter sw = new StreamWriter(_filePath, _append))
                {
                    sw.Write(_dataString);
                    sw.Flush();
                    sw.Close();
                }
                result = true;
            }
            catch
            {
                result = false;
            }
            return result;
        }
    } 
    #endregion


}