using Newtonsoft.Json;
using System;
using System.IO;
using System.Text;
using UnityEngine;
namespace XRTool.Util
{
    public enum LogLevel
    {
        NO = 0,
        Low = 1,
        Middle = 2,
        High = 3,
        Max = 4
    }
    /// <summary>
    /// 日志输出,请勿使用Debug或者Print等自带的日志
    /// 日志分级,普通日志,错误日志,异常日志
    /// debug模式可以输出普通日志,其他日志必输出
    /// 通过配置参数实现不同的日志等级
    /// 为了避免大量日志输出,采用优化方案写入日志
    /// </summary>
    public static class UnityLog
    {
        private static string logBuilder;
        private static FileStream logStream;
        private static FileStream errorStream;
        private static FileStream exceptStream;
        public static event Action<string> MessageReceived;
        /// <summary>
        /// 在编辑器中是否输出日志文件
        /// </summary>
        public static bool isOutLogEditor = true;
        /// <summary>
        /// 日志等级,默认为1,正式发布版本为0
        /// 等级越高代表可输出的日志越多
        /// </summary>
        public static int logLevel = 1;
        public const string NULL = "null";
        private static bool isFristLog = true;
        private static bool isFristLogError = true;
        private static bool isFristLogExcept = true;
        private static string logPath;
        public static FileStream LogStream
        {
            get
            {
                if (logStream == null)
                {
                    logStream = new FileStream(Path.Combine(LogPath, "log.txt"), FileMode.Append);
                }
                return logStream;
            }
        }
        public static FileStream ErrorStream
        {
            get
            {
                if (errorStream == null)
                {
                    errorStream = new FileStream(Path.Combine(LogPath, "error.txt"), FileMode.Append);
                }
                return errorStream;
            }
        }
        public static FileStream ExceptStream
        {
            get
            {
                if (exceptStream == null)
                {
                    exceptStream = new FileStream(Path.Combine(LogPath, "except.txt"), FileMode.Append);
                }
                return exceptStream;
            }
        }

        public static string LogPath { get => logPath; set => logPath = value; }

        static UnityLog()
        {
            /*
            if (BuildConfigMgr.Instance.IsInit) { }*/
            //LogPath = Path.Combine(BuildConfig.Instance.UserPath, "LogData");
            LogPath = Path.Combine(Application.persistentDataPath, "LogData");
            if (!Directory.Exists(LogPath))
            {
                Directory.CreateDirectory(LogPath);
            }
            else
            {
                ///缓存文件最大只留10M,超过10M后,清除日志
                DirectoryInfo di = new DirectoryInfo(LogPath);
                long len = 0;
                foreach (FileInfo item in di.GetFiles())
                {
                    len += item.Length;
                }
                if (len > 10 * UnityUtil.MB)
                {
                    Directory.Delete(LogPath, true);
                }
                Directory.CreateDirectory(LogPath);
            }
            Application.logMessageReceived += LogMessageReceived;

            //InitLog();
        }
        /// <summary>
        /// 接受系统日志
        /// </summary>
        /// <param name="condition"></param>
        /// <param name="stackTrace"></param>
        /// <param name="type"></param>
        private static void LogMessageReceived(string condition, string stackTrace, LogType type)
        {
            if (!isOutLogEditor)
            {
                return;
            }
            logBuilder = null;
            FileStream fileStream = null;
            if (string.IsNullOrEmpty(condition) && string.IsNullOrEmpty(stackTrace))
            {
                return;
            }
            bool isWriteFrist = false;
#if UNITY_EDITOR || !BUILDTYPE_RELEASE //Release  
            if (type == LogType.Log)
            {
                ///日志等级大于0时才会开启日志
                if (logLevel >= 1)
                {
                    fileStream = LogStream;
                }
                if (isFristLog)
                {
                    isWriteFrist = true;
                    isFristLog = false;
                }
            }
#endif
            if (type == LogType.Exception)
            {
                fileStream = ExceptStream;
                if (isFristLogExcept)
                {
                    isWriteFrist = true;
                    isFristLogExcept = false;
                }
            }
            else if (type == LogType.Error)
            {
                fileStream = ErrorStream;
                if (isFristLogError)
                {
                    isWriteFrist = true;
                    isFristLogError = false;
                }
            }
            if (fileStream != null)
            {
                DateTime time = DateTime.Now;
                logBuilder = time + ": " + condition + stackTrace + "\n";
                MessageReceived?.Invoke(logBuilder);
                if (isWriteFrist)
                {
                    /*
                    if (BuildConfigMgr.Instance.IsInit)
                    {
                        ReleaseLog("\n----------Version Log------------\n" +
                            Application.productName + "_" + Application.version + "_" + JsonConvert.SerializeObject(BuildConfig.Instance) + "\n",
                            fileStream);
                    }*/
                }
                ReleaseLog(logBuilder, fileStream);
                fileStream.Flush();
            }
            fileStream = null;
            logBuilder = null;
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public static void ReleaseLog()
        {
            Application.logMessageReceived -= LogMessageReceived;
            if (logStream != null)
            {
                logStream.Close();
            }
            if (errorStream != null)
            {
                errorStream.Close();
            }
            if (exceptStream != null)
            {
                exceptStream.Close();
            }
            logStream = null;
            errorStream = null;
            exceptStream = null;
        }
        public static void Log(object log, int level = 1)
        {
            //Log(log != null ? log.ToString() : "null", logLevel);
            ///如果是编辑器模式或者非商用APP版本,可以打日志文件
#if UNITY_EDITOR || !BuildType_RELEASE //Release
            bool isForce = false;
#if UNITY_EDITOR
            isForce = logLevel >= 4;
#endif
            if (isForce || level <= logLevel)
            {
                Debug.Log(log != null ? log.ToString() : NULL);
            }
#endif
        }
        /// <summary>
        /// 正常的日志输出
        /// </summary>
        public static void Log(string log, int level = 1)
        {
            ///如果是编辑器模式或者非商用APP版本,可以打日志文件
#if UNITY_EDITOR || !BuildType_RELEASE //Release
            bool isForce = false;
#if UNITY_EDITOR
            isForce = logLevel >= 4;
#endif
            if (isForce || level <= logLevel)
            {
                Debug.Log(log);
            }
#endif
        }



        /// <summary>
        /// 错误日志输出
        /// </summary>
        public static void LogError(string log, int logLevel = 1)
        {
            ///错误日志任何模式都会输出
            Debug.Log(log);
        }
        /// <summary>
        /// 错误日志输出
        /// </summary>
        public static void LogException(Exception ex, int level = 1)
        {
            ///异常日志由系统自动输出
            Debug.LogException(ex);
        }
        /// <summary>
        /// 日志输出,替换对应的日志文件
        /// </summary>
        public static void Log(string log, LogType logType, int logLevel = 1)
        {
            if (logType == LogType.Log)
            {
                Log(log, logLevel);
            }

            else if (logType == LogType.Error)
            {
                LogError(log, logLevel);
            }
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public static void ReleaseLog(string msg, FileStream stream)
        {
            if (!string.IsNullOrEmpty(msg))
            {
                WriteLogToFile(msg, stream);
            }
        }

        /// <summary>
        /// 将日志写入到文件中
        /// </summary>
        /// <param name="log"></param>
        /// <param name="logType"></param>
        public static void WriteLogToFile(string log, FileStream stream)
        {
            if (stream != null)
            {
                ///UTF8的编码格式转化成byte字节流
                byte[] buttf = Encoding.Default.GetBytes(log);
                stream.Write(buttf, 0, log.Length);
            }
        }

        public static void ClearAllLog()
        {
            ReleaseLog();
            if (Directory.Exists(LogPath))
            {
                Directory.Delete(LogPath, true);
            }
            Directory.CreateDirectory(LogPath);
            //InitLog(FileMode.Create);
        }
    }
}