/********************************
 *
 * 作者:吴隆健
 * 创建时间: 2019-06-09 10:31:40
 * 
 ********************************/

using MrWu.Time;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MrWu.Debug
{
    /// <summary>
    /// 日志池
    /// </summary>
    public class LogPool : IDebug
    {

        private LogPool(LogConfig config) {
            this.config = config;
            var now = DateTime.Now;
            //if(!string.IsNullOrEmpty(config.logpath)) {
            logWriter = GetWriter(now);
            //}

            // 下一版再启用
            var dueTime = (int)(now.Date.AddDays(1) - now).TotalMilliseconds;
            //var dueTime = (int)(now.AddMinutes(1) - now).TotalMilliseconds; //测试
            var period = (int)TimeSpan.FromDays(1).TotalMilliseconds;
            this.logTaskTimer = new Timer(ZeroTask, null, dueTime, period);
        }


        /// <summary>
        /// 零时任务
        /// </summary>
        /// <param name="obj"></param>
        void ZeroTask(object obj) {
            var now = DateTime.Now;
            SwitchWriter(now);
            DeleteOutdateLogFiles(now);
        }

        /// <summary>
        /// 更换 logWriter
        /// </summary>
        /// <param name="now">当前时间</param>
        void SwitchWriter(DateTime now) {
            using (var oldWriter = this.logWriter) {
                var newWriter = GetWriter(now);
                this.logWriter = newWriter;
                oldWriter.Flush();
            }
        }

        /// <summary>
        /// 删除过期日志文件
        /// </summary>
        /// <param name="now">当前时间</param>
        void DeleteOutdateLogFiles(DateTime now) {
            var logFiles = new DirectoryInfo(Directory.GetCurrentDirectory() + "/logs").GetFiles("*.log");
            var outDateLogs = logFiles.Where(p => p.CreationTime.AddDays(config.remainDays) < now).ToList();

            outDateLogs.ForEach(p => {
                try {
                    p.Delete();
                } catch (Exception ex) {
                    AddLog($"删除过时日志文件时发生异常!\t{ex.Message}", DebugLevel.Warning);
                }
            });
        }

        StreamWriter GetWriter(DateTime dateTime) {

            string path = Directory.GetCurrentDirectory() + "/logs";
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);

            return new StreamWriter(path + "/" + getLogFileName(dateTime)/*, false, Encoding.UTF8, 300 * 1024*/);
        }

        /// <summary>
        /// 定时任务 Timer
        /// </summary>
        Timer logTaskTimer {
            get;
        }

        string getLogFileName(DateTime curDatetime) {
            return curDatetime.TimeToString(TimeStyle.MMddhhmmss, string.Empty, string.Empty, string.Empty) + ".log";
        }

        /// <summary>
        /// 实例
        /// </summary>
        private static LogPool instance;

        /// <summary>
        /// 启动
        /// </summary>
        /// <param name="config"></param>
        public static void Start(LogConfig config) {
            if (config != null) {
                instance = new LogPool(config);
                saveLevel = config.saveLevel;
                Debug.Start(instance, config.logLevel);
            }
        }

        /// <summary>
        /// 日志流
        /// </summary>
        private StreamWriter logWriter {
            get; set;
        }

        /// <summary>
        /// 配置
        /// </summary>
        public readonly LogConfig config;

        /// <summary>
        /// 日志
        /// </summary>
       // private readonly List<LogMessage> logs = new List<LogMessage>();

        private readonly Queue<LogMessage> logs = new Queue<LogMessage>();

        /// <summary>
        /// 重要信息
        /// </summary>
        private readonly Queue<LogMessage> Infos = new Queue<LogMessage>();

        /// <summary>
        /// 警告
        /// </summary>
        private readonly Queue<LogMessage> warnings = new Queue<LogMessage>();

        /// <summary>
        /// 重要日志
        /// </summary>
        private readonly Queue<LogMessage> ImportantLogs = new Queue<LogMessage>();

        /// <summary>
        /// 错误
        /// </summary>
        private readonly Queue<LogMessage> errors = new Queue<LogMessage>();

        /// <summary>
        /// 致命的错误
        /// </summary>
        private readonly Queue<LogMessage> Fatals = new Queue<LogMessage>();

        private readonly object logidLock = new object();
        private ulong _logid = 0;
        private ulong logid {
            get {
                ulong value;
                lock (logidLock) {
                    _logid++;
                    value = _logid;
                }
                return value;
            }
        }

        private ulong GetLogId() {
            lock (logidLock) {
                return _logid;
            }
        }

        /// <summary>
        /// 日志缓存数量
        /// </summary>
        public int logCacheCount => config.logCacheCount;

        /// <summary>
        /// 信息缓存数量
        /// </summary>
        public int InfoCacheCount => config.InfoCacheCount;

        /// <summary>
        /// 警告缓存数量
        /// </summary>
        public int warningCacheCount => config.warningCacheCount;

        /// <summary>
        /// 重要日志数量
        /// </summary>
        public int ImportantLogCaheCount => config.ImportantLogCacheCount;

        /// <summary>
        /// 错误数量
        /// </summary>
        public int errorCacheCount => config.errorCacheCount;

        /// <summary>
        /// 致命错误
        /// </summary>
        public int FatalCacheCount => config.FatalCacheCount;

        private static ulong _logCount;

        /// <summary>
        /// 日志数量
        /// </summary>
        public static ulong logCount {
            get {
                return _logCount;
            }
            private set {
                _logCount = value;
            }
        }

        private static ulong _InfoCount;

        /// <summary>
        /// 信息数量
        /// </summary>
        public static ulong InfoCount {
            get {
                return _InfoCount;
            }
            private set {
                _InfoCount = value;
            }
        }

        private static ulong _warningCount;

        /// <summary>
        /// 警告数量
        /// </summary>
        public static ulong warningCount {
            get => _warningCount;
            private set {
                _warningCount = value;
            }
        }

        private static ulong _ImportantlogCount;

        /// <summary>
        /// 重要日志数量
        /// </summary>
        public static ulong ImportantlogCount {
            get => _ImportantlogCount;
            private set {
                _ImportantlogCount = value;
            }
        }

        private static ulong _errorCount;

        /// <summary>
        /// 错误总数量
        /// </summary>
        public static ulong errorCount {
            get => _errorCount;
            private set {
                _errorCount = value;
            }
        }

        private static ulong _fatalCount;

        /// <summary>
        /// 致命错误数量
        /// </summary>
        public static ulong fatalCount {
            get => _fatalCount;
            private set {
                _fatalCount = value;
            }
        }

        /// <summary>
        /// 锁定物体
        /// </summary>
        private readonly object lockObj = new object();

        /// <summary>
        /// 锁写日志
        /// </summary>
        private readonly object lockWrite = new object();

        /// <summary>
        /// 锁定日志临时缓存
        /// </summary>
        private readonly object locktmpCache = new object();

        /// <summary>
        /// 临时缓存日志
        /// </summary>
        private Queue<LogMessage> tmpCachelog = new Queue<LogMessage>();

        /// <summary>
        /// 保存日志
        /// </summary>
        public static DebugLevel saveLevel {
            get {
                return m_saveLevel;
            }
            set {
                m_saveLevel = value;
                if(SaveLevelChange != null)
                    SaveLevelChange(m_saveLevel);
            }
        }

        private static DebugLevel m_saveLevel;

        /// <summary>
        /// 保存日志的等级变化事件
        /// </summary>
        public static event Action<DebugLevel> SaveLevelChange;

        /// <summary>
        /// 手动刷新日志文本
        /// </summary>
        public static void Flush() {
            if (instance != null) {
                instance.FlushFile();
            }
        }

        /// <summary>
        /// 刷新日志文件
        /// </summary>
        private void FlushFile() {
            var writer = this.logWriter;
            if (writer != null) {
                lock (lockWrite) {
                    writer.Flush();
                }
            }
        }

        /// <summary>
        /// 接收到日志
        /// </summary>
        /// <param name="str">日志内容</param>
        /// <param name="level">日志等级 1 普通日志   5警告   10错误日志</param>
        public void AddLog(string str, DebugLevel level) {
            LogMessage msg = new LogMessage(logid, level, str);
            var writer = this.logWriter;
            if (writer != null && ((level & saveLevel) != 0)) {
                lock (lockWrite) {
                    writer.WriteLine(msg.logstr);
                    writer.Flush();
                }
            }
            //Task.Factory.StartNew(
            //    () => {
            //下一版再启用! 挪到外部处理走事件
            //CollectLoggings.Enqueue(msg);
            //if (CollectLoggings.Count > 500000) {
            //    //暂存周期为5分钟，日志容器容量为150000，预估最大日志量：3000条 / 每分钟, 足够容纳10个周期的日志量，超期的将不会提交到日志收集模块而被丢弃，但本地保存
            //    CollectLoggings.TryDequeue(out var _);
            //}
            lock (locktmpCache) {
                tmpCachelog.Enqueue(msg);
            }


            lock (lockObj) {
                switch (level) {  //设置日志数量
                    case DebugLevel.Log:
                        logCount++;
                        ReleaseFrist(logs, msg, logCacheCount);
                        break;
                    case DebugLevel.Info:
                        logCount++;
                        ReleaseFrist(Infos, msg, InfoCacheCount);
                        break;
                    case DebugLevel.Warning:
                        warningCount++;
                        ReleaseFrist(warnings, msg, warningCacheCount);
                        break;
                    case DebugLevel.ImportantLog:
                        ImportantlogCount++;
                        ReleaseFrist(ImportantLogs, msg, ImportantLogCaheCount);
                        break;
                    case DebugLevel.Error:
                        errorCount++;
                        ReleaseFrist(errors, msg, errorCacheCount);
                        break;
                    case DebugLevel.Fatal:
                        fatalCount++;
                        ReleaseFrist(Fatals, msg, FatalCacheCount);
                        break;
                }
            }
            //  }
            //);
        }

        /*
        /// <summary>
        /// 如果超过限制，移除并释放第一个
        /// </summary>
        /// <param name="list"></param>
        /// <param name="newLog"></param>
        /// <param name="limit"></param>
        void ReleaseFrist(List<LogMessage> list, LogMessage newLog, int limit) {
            list.Add(newLog);
            if (list.Count > limit) {
                //var log = list[0];
                list.RemoveAt(0);
            }
        }
        */

        /// <summary>
        /// 如果超过限制，移除并释放第一个
        /// </summary>
        /// <param name="list"></param>
        /// <param name="newLog"></param>
        /// <param name="limit"></param>
        void ReleaseFrist(Queue<LogMessage> list, LogMessage newLog, int limit) {
            list.Enqueue(newLog);
            if (list.Count > limit) {
                //var log = list[0];
                list.Dequeue();
            }

        }


        /// <summary>
        /// 上次获取日志的等级
        /// </summary>
        private DebugLevel lastGetLevel = (DebugLevel)(-1);

        /// <summary>
        /// 日志id
        /// </summary>
        private ulong log_id = 0;

        private ulong Info_id = 0;

        /// <summary>
        /// 警告id
        /// </summary>
        private ulong warning_id = 0;

        /// <summary>
        /// 重要日志
        /// </summary>
        private ulong ImportantLog_id = 0;

        /// <summary>
        /// 错误id
        /// </summary>
        private ulong error_id = 0;

        /// <summary>
        /// 致命的id
        /// </summary>
        private ulong fatal_id = 0;

        /// <summary>
        /// 获取这段时间的日志
        /// </summary>
        /// <param name="tmplogs"></param>
        /// <param name="tmpinfos"></param>
        /// <param name="tmpwarnings"></param>
        /// <param name="tmpimportantLogs"></param>
        /// <param name="tmperrors"></param>
        /// <param name="tmpfatal"></param>
        /// <param name="level"></param>
        /// <returns></returns>
        private string ResetlogStrs(List<LogMessage> tmplogs, List<LogMessage> tmpinfos, List<LogMessage> tmpwarnings, List<LogMessage> tmpimportantLogs, List<LogMessage> tmperrors, List<LogMessage> tmpfatal, DebugLevel level) {

            void setlogsId(List<LogMessage> _logs, List<LogMessage> _infos, List<LogMessage> _warnings,
                           List<LogMessage> _importantLogs, List<LogMessage> _errors, List<LogMessage> _fatals) {

                if (_logs.Count == 0)
                    log_id = 0;
                else
                    log_id = _logs[_logs.Count - 1].logid;

                if (_infos.Count == 0)
                    Info_id = 0;
                else
                    Info_id = _infos[_infos.Count - 1].logid;

                if (_warnings.Count == 0)
                    warning_id = 0;
                else
                    warning_id = _warnings[_warnings.Count - 1].logid;

                if (_importantLogs.Count == 0)
                    ImportantLog_id = 0;
                else
                    ImportantLog_id = _importantLogs[_importantLogs.Count - 1].logid;

                if (_errors.Count == 0)
                    error_id = 0;
                else
                    error_id = _errors[_errors.Count - 1].logid;

                if (_fatals.Count == 0)
                    fatal_id = 0;
                else
                    fatal_id = _fatals[_fatals.Count - 1].logid;
            }

            StringBuilder logStrs = new StringBuilder();
            lastGetLevel = level;

            bool islog = (tmplogs.Count > 0) && ((lastGetLevel & DebugLevel.Log) != 0);
            bool isInfo = (tmpinfos.Count > 0) && ((lastGetLevel & DebugLevel.Info) != 0);
            bool isWarning = (tmpwarnings.Count > 0) && ((lastGetLevel & DebugLevel.Warning) != 0);
            bool isImportantLog = (tmpimportantLogs.Count > 0) && ((lastGetLevel & DebugLevel.ImportantLog) != 0);
            bool isError = (tmperrors.Count > 0) && ((lastGetLevel & DebugLevel.Error) != 0);
            bool isFatal = (tmpfatal.Count > 0) && ((lastGetLevel & DebugLevel.Fatal) != 0);

            int logidx = 0;
            int infoIdx = 0;
            int warningidx = 0;
            int ImportantLogIdx = 0;
            int erroridx = 0;
            int fatalIdx = 0;

            DebugLevel mingDebugLevel = (DebugLevel)0;
            ulong minlogidValue = ulong.MaxValue;

            while (true) {
                if (islog) {
                    if (tmplogs[logidx].logid < minlogidValue) {
                        minlogidValue = tmplogs[logidx].logid;
                        mingDebugLevel = DebugLevel.Log;
                    }
                }
                if (isInfo) {
                    if (tmpinfos[infoIdx].logid < minlogidValue) {
                        minlogidValue = tmpinfos[infoIdx].logid;
                        mingDebugLevel = DebugLevel.Info;
                    }
                }
                if (isWarning) {
                    if (tmpwarnings[warningidx].logid < minlogidValue) {
                        minlogidValue = tmpwarnings[warningidx].logid;
                        mingDebugLevel = DebugLevel.Warning;
                    }
                }
                if (isImportantLog) {
                    if (tmpimportantLogs[ImportantLogIdx].logid < minlogidValue) {
                        minlogidValue = tmpimportantLogs[ImportantLogIdx].logid;
                        mingDebugLevel = DebugLevel.ImportantLog;
                    }
                }
                if (isError) {
                    if (tmperrors[erroridx].logid < minlogidValue) {
                        minlogidValue = tmperrors[erroridx].logid;
                        mingDebugLevel = DebugLevel.Error;
                    }
                }
                if (isFatal) {
                    if (tmpfatal[fatalIdx].logid < minlogidValue) {
                        minlogidValue = tmpfatal[fatalIdx].logid;
                        mingDebugLevel = DebugLevel.Fatal;
                    }
                }
                switch (mingDebugLevel) {
                    case DebugLevel.Log:
                        logStrs.AppendLine(tmplogs[logidx++].logstr);
                        break;
                    case DebugLevel.Info:
                        logStrs.AppendLine(tmpinfos[infoIdx++].logstr);
                        break;
                    case DebugLevel.Warning:
                        logStrs.AppendLine(tmpwarnings[warningidx++].logstr);
                        break;
                    case DebugLevel.ImportantLog:
                        logStrs.AppendLine(tmpimportantLogs[ImportantLogIdx++].logstr);
                        break;
                    case DebugLevel.Error:
                        logStrs.AppendLine(tmperrors[erroridx++].logstr);
                        break;
                    case DebugLevel.Fatal:
                        logStrs.AppendLine(tmpfatal[fatalIdx++].logstr);
                        break;
                }

                if (logidx >= tmplogs.Count)
                    islog = false;
                if (infoIdx >= tmpinfos.Count)
                    isInfo = false;
                if (warningidx >= tmpwarnings.Count)
                    isWarning = false;
                if (ImportantLogIdx >= tmpimportantLogs.Count)
                    isImportantLog = false;
                if (erroridx >= tmperrors.Count)
                    isError = false;
                if (fatalIdx >= tmpfatal.Count)
                    isFatal = false;

                if (!islog && !isWarning && !isError && !isInfo && !isImportantLog && !isFatal)
                    break;
                minlogidValue = long.MaxValue;
            }
            setlogsId(tmplogs, tmpinfos, tmpwarnings, tmpimportantLogs, tmperrors, tmpfatal);

            lock (locktmpCache) {
                tmpCachelog.Clear();
            }

            return logStrs.ToString();
        }

        private StringBuilder incLogCache = new StringBuilder();

        /// <summary>
        /// 增量获取日志
        /// </summary>
        private string AddLogs() {
            Queue<LogMessage> tmp;
            lock (locktmpCache) {
                tmp = tmpCachelog;
                tmpCachelog = new Queue<LogMessage>();
            }

            while (tmp.Count > 0) {
                incLogCache.AppendLine(tmp.Dequeue().logstr);
            }
            string result = incLogCache.ToString();
            if (result == null)
                result = string.Empty;
            incLogCache.Clear();
            return result;
            /*
            StringBuilder logStrs = new StringBuilder();
            bool islog = (logs.Count > 0) && ((lastGetLevel & DebugLevel.Log) != 0);
            bool isInfo = (Infos.Count > 0) && ((lastGetLevel & DebugLevel.Info) != 0);
            bool isWarning = (warnings.Count > 0) && ((lastGetLevel & DebugLevel.Warning) != 0);
            bool isImportantLog = (ImportantLogs.Count > 0) && ((lastGetLevel & DebugLevel.ImportantLog) != 0);
            bool isError = (errors.Count > 0) && ((lastGetLevel & DebugLevel.Error) != 0);
            bool isFatal = (Fatals.Count > 0) && ((lastGetLevel & DebugLevel.Fatal) != 0);

            //增量如何删除
            DebugLevel mingDebugLevel = (DebugLevel)0;
            ulong minlogidValue = ulong.MaxValue;

            int logidx = 0;
            int infoidx = 0;
            int warningidx = 0;
            int importantIdx = 0;
            int erroridx = 0;
            int fatalidx = 0;

            if (islog) {
                for (int i = logs.Count - 1; i >= 0; i--) {
                    if (logs[i].logid == log_id) {
                        logidx = i + 1;
                        break;
                    }
                }
                islog = logidx < logs.Count;
            }

            if (isInfo) {
                for (int i = Infos.Count - 1; i >= 0; i--) {
                    if (Infos[i].logid == Info_id) {
                        logidx = i + 1;
                        break;
                    }
                }
                isInfo = logidx < Infos.Count;
            }

            if (isWarning) {
                for (int i = warnings.Count - 1; i >= 0; i--) {
                    if (warnings[i].logid == warning_id) {
                        warningidx = i + 1;
                        break;
                    }
                }
                isWarning = warningidx < warnings.Count;
            }

            if (isImportantLog) {
                for (int i = ImportantLogs.Count - 1; i >= 0; i--) {
                    if (ImportantLogs[i].logid == ImportantLog_id) {
                        importantIdx = i + 1;
                        break;
                    }
                }
                isImportantLog = importantIdx < ImportantLogs.Count;
            }

            if (isError) {
                for (int i = errors.Count - 1; i >= 0; i--) {
                    if (errors[i].logid == error_id) {
                        erroridx = i + 1;
                        break;
                    }
                }
                isError = erroridx < errors.Count;
            }

            if (isFatal) {
                for (int i = Fatals.Count - 1; i >= 0; i--) {
                    if (Fatals[i].logid == fatal_id) {
                        fatalidx = i + 1;
                        break;
                    }
                }
                isFatal = fatalidx < Fatals.Count;
            }

            while (true) {
                if (islog) {
                    if (logs[logidx].logid < minlogidValue) {
                        minlogidValue = logs[logidx].logid;
                        mingDebugLevel = DebugLevel.Log;
                    }
                }
                if (isInfo) {
                    if (Infos[infoidx].logid < minlogidValue) {
                        minlogidValue = Infos[infoidx].logid;
                        mingDebugLevel = DebugLevel.Info;
                    }
                }
                if (isWarning) {
                    if (warnings[warningidx].logid < minlogidValue) {
                        minlogidValue = warnings[warningidx].logid;
                        mingDebugLevel = DebugLevel.Warning;
                    }
                }
                if (isImportantLog) {
                    if (ImportantLogs[importantIdx].logid < minlogidValue) {
                        minlogidValue = ImportantLogs[importantIdx].logid;
                        mingDebugLevel = DebugLevel.ImportantLog;
                    }
                }
                if (isError) {
                    if (errors[erroridx].logid < minlogidValue) {
                        minlogidValue = errors[erroridx].logid;
                        mingDebugLevel = DebugLevel.Error;
                    }
                }
                if (isFatal) {
                    if (Fatals[fatalidx].logid < minlogidValue) {
                        minlogidValue = Fatals[fatalidx].logid;
                        mingDebugLevel = DebugLevel.Fatal;
                    }
                }

                switch (mingDebugLevel) {
                    case DebugLevel.Log:
                        logStrs.AppendLine(logs[logidx++].logstr);
                        break;
                    case DebugLevel.Info:
                        logStrs.AppendLine(Infos[infoidx++].logstr);
                        break;
                    case DebugLevel.Warning:
                        logStrs.AppendLine(warnings[warningidx++].logstr);
                        break;
                    case DebugLevel.ImportantLog:
                        logStrs.AppendLine(ImportantLogs[importantIdx++].logstr);
                        break;
                    case DebugLevel.Error:
                        logStrs.AppendLine(errors[erroridx++].logstr);
                        break;
                    case DebugLevel.Fatal:
                        logStrs.AppendLine(Fatals[fatalidx++].logstr);
                        break;
                }

                if (logidx >= logs.Count)
                    islog = false;
                if (infoidx >= Infos.Count)
                    isInfo = false;
                if (warningidx >= warnings.Count)
                    isWarning = false;
                if (importantIdx >= ImportantLogs.Count)
                    isImportantLog = false;
                if (erroridx >= errors.Count)
                    isError = false;
                if (fatalidx >= Fatals.Count)
                    isFatal = false;
                if (!islog && !isWarning && !isError && !isInfo && !isImportantLog && !isFatal)
                    break;
                minlogidValue = long.MaxValue;
            }
            setlogsId();
            return logStrs.ToString();
            */
        }

        /// <summary>
        /// 获取日志_只获取增量
        /// </summary>
        /// <param name="level">日志等级</param>
        /// <returns></returns>
        public static string GetLog(DebugLevel level = DebugLevel.Log | DebugLevel.Warning | DebugLevel.Error) {
            if (instance == null)
                return string.Empty;
            string result;
            if (level != instance.lastGetLevel) {
                List<LogMessage> tmplogs = null;
                List<LogMessage> tmpinfos = null;
                List<LogMessage> tmpwarnings = null;
                List<LogMessage> tmpimportantLogs = null;
                List<LogMessage> tmperrors = null;
                List<LogMessage> tmpfatal = null;
                lock (instance.lockObj) {
                    tmplogs = new List<LogMessage>(instance.logs);
                    tmpinfos = new List<LogMessage>(instance.Infos);
                    tmpwarnings = new List<LogMessage>(instance.warnings);
                    tmpimportantLogs = new List<LogMessage>(instance.ImportantLogs);
                    tmperrors = new List<LogMessage>(instance.errors);
                    tmpfatal = new List<LogMessage>(instance.Fatals);
                }
                result = instance.ResetlogStrs(tmplogs, tmpinfos, tmpwarnings, tmpimportantLogs, tmperrors, tmpfatal, level);
            } else {
                result = instance.AddLogs();
            }

            return result;
        }

        /*
        /// <summary>
        /// GetLoggings
        /// </summary>
        /// <param name="currentSeq">当前日志序号</param>
        /// <returns></returns>
        public static LogMessage[] GetLoggings(out ulong currentSeq) {
            currentSeq = instance.GetLogId();
            var seq = currentSeq;
            return CollectLoggings.Where(p => p.logid <= seq).ToArray();
        }

        /// <summary>
        /// 日志暂存容器，
        /// </summary>
        static ConcurrentQueue<LogMessage> CollectLoggings { get; } = new ConcurrentQueue<LogMessage>();
        static ConcurrentDictionary<ulong, LogMessage> msgs { get; } = new ConcurrentDictionary<ulong, LogMessage>();


        /// <summary>
        /// ClearLogging
        /// </summary>
        /// <param name="currentSeq">日志序号</param>
        public static void ClearLogging(ulong currentSeq) {
            while (CollectLoggings.Count > 0) {
                if (CollectLoggings.TryPeek(out var log)) {
                    if (log.logid <= currentSeq) {
                        CollectLoggings.TryDequeue(out log);
                    } else {
                        break;
                    }
                } else {
                    break;
                }
            }
        }
        */
    }
}