﻿using System;
using System.IO;
using System.Windows.Forms;
using SGLibrary.Extend;

namespace SGLibrary.Framework.Log
{
    /// <summary>
    /// 这个日志类不适用于Web,因为定时器的原因
    /// Web请用ThreadSafeLogText
    /// </summary>
    public class SimpleLogImpl_Text : SimpleLogBase, ISimpleLog, IDisposable
    {
        public SimpleLogImpl_Text(String LogFileName, Boolean Append, UInt32 PushTime,
            LogLevel level)
        {
            this.Level = level;
            this.LogFileName = LogFileName;
            this.Append = Append;
            this.PushTime = PushTime;

            Application.ApplicationExit += new EventHandler(ApplicationExit);
            BeginTime = DateTime.Now;
        }

        public LogLevel Level { get; private set; }

        private String BeginEndStr = new String('=', 40);
        private StreamWriter txt = null;
        private DateTime BeginTime;
        private System.Windows.Forms.Timer timer;

        private Boolean Append;
        private UInt32 PushTime;

        public String LogFileName { get; private set; }

        private Boolean newLog;
        private Boolean NewLog
        {
            get { return newLog; }
            set
            {
                if (PushTime > 0)
                    newLog = value;
                else if (value && txt != null)
                    txt.Flush();
            }
        }

        private void ApplicationExit(object sender, EventArgs e)
        {
            this.End();
        }

        public override string ToString()
        {
            return this.LogFileName;
        }

        private Boolean makeReadyFile()
        {
            if (txt != null)
                return true;

            if (!ExIO.MakeReadyFileDir(LogFileName))
                return false;

            txt = new StreamWriter(LogFileName, Append);
            txt.WriteLine(BeginEndStr);
            txt.WriteLine("Begin: " + BeginTime.ToString());
            if (BeginTime == DateTime.MaxValue)
                txt.WriteLine("关闭" + LogFileName + "后还试图向其写以下内容：");

            if (PushTime > 0)
            {
                timer = new System.Windows.Forms.Timer();
                timer.Interval = (Int32)PushTime;
                timer.Tick += new EventHandler(Push);
                timer.Start();
            }
            return true;
        }

        internal void Push(object sender, EventArgs e)
        {
            if ((txt == null) || !NewLog)
                return;

            txt.Flush();
            NewLog = false;
        }

        public void Dispose()
        {
            End();
        }

        public void WriteStr(String Str)
        {
            if (makeReadyFile())
            {
                txt.WriteLine(Str);
                NewLog = true;
            }
        }

        public override void Debug(object message, Exception exception)
        {
            if ((Int32)this.Level < (Int32)LogLevel.All)
                return;

            if (makeReadyFile())
            {
                txt.WriteLine(this.GetLogItemHead(LogLevel.All)
                    + " " + this.GetLogItem(message, exception));
                NewLog = true;
            }
        }

        public override void Info(object message, Exception exception)
        {
            if ((Int32)this.Level < (Int32)LogLevel.Info)
                return;

            if (makeReadyFile())
            {
                txt.WriteLine(this.GetLogItemHead(LogLevel.Info)
                    + " " + this.GetLogItem(message, exception));
                NewLog = true;
            }
        }

        public override void Warn(object message, Exception exception)
        {
            if ((Int32)this.Level < (Int32)LogLevel.Warn)
                return;

            if (makeReadyFile())
            {
                txt.WriteLine(this.GetLogItemHead(LogLevel.Warn)
                    + " " + this.GetLogItem(message, exception));
                NewLog = true;
            }
        }

        public override void Error(object message, Exception exception)
        {
            if ((Int32)this.Level < (Int32)LogLevel.Error)
                return;

            if (makeReadyFile())
            {
                txt.WriteLine(this.GetLogItemHead(LogLevel.Error)
                    + " " + this.GetLogItem(message, exception));
                NewLog = true;
            }
        }

        public override void Fatal(object message, Exception exception)
        {
            if ((Int32)this.Level < (Int32)LogLevel.Fatal)
                return;

            if (makeReadyFile())
            {
                txt.WriteLine(this.GetLogItemHead(LogLevel.Fatal)
                    + " " + this.GetLogItem(message, exception));
                NewLog = true;
            }
        }

        public override void End()
        {
            if (txt == null)
                return;

            if (timer != null)
                timer.Stop();

            txt.WriteLine("End: " + DateTime.Now.ToString());
            txt.WriteLine(BeginEndStr);
            txt.WriteLine("");
            txt.Close();

            //没啥意义，防止开发人员程序逻辑错误
            txt = null;
            NewLog = false;
            BeginTime = DateTime.MaxValue;
            timer = null;
        }
    }
}
