using System;
using System.Configuration;
using System.IO;
using System.Threading.Tasks;

namespace Mall.Common.Plugin
{
    /// <summary>
    /// 日志帮助类
    /// </summary>
    public class LogHelper
    {
        private static string logDir = Config.LogPath;
        private static string infoLogDir = Config.InofLogPath;
        private static string requestLogDir = Config.RequestLogPath;
        private static object objError = new object();
        private static object objInfo = new object();
        private static object objRequest = new object();

        /// <summary>
        /// 构造函数
        /// </summary>
        static LogHelper()
        {
            if (!Directory.Exists(logDir))
                Directory.CreateDirectory(logDir);
            if (!Directory.Exists(infoLogDir))
                Directory.CreateDirectory(infoLogDir);
            if (!Directory.Exists(requestLogDir))
                Directory.CreateDirectory(requestLogDir);
        }

        /// <summary>
        /// 错误日志
        /// </summary>
        /// <param name="msg">信息</param>
        /// <param name="exception">异常内容</param>
        public static void Error(string msg, Exception exception)
        {
            Write(exception, msg);
        }


        /// <summary>
        /// 写日志(异常日志)
        /// </summary>
        /// <param name="ex">异常内容</param>
        public static void Write(Exception ex)
        {
            Write(ex, "");
        }

        /// <summary>
        /// 写日志(异常日志)
        /// </summary>
        /// <param name="msg">信息</param>
        public static void Write(string msg)
        {
            Write(null, msg);
        }

        /// <summary>
        /// 写日志(异常日志)
        /// </summary>
        /// <param name="exception">异常信息</param>
        /// <param name="otherMsg">其他信息</param>
        public static void Write(Exception exception, string otherMsg)
        {
            Task.Run(() => WriteLog(exception, otherMsg, LogEnum.Error));
        }

        /// <summary>
        /// 打印信息(记录信息)
        /// </summary>
        /// <param name="msg">信息</param>
        public static void WriteInfo(string msg)
        {
            Task.Run(() => WriteLog(null, msg, LogEnum.Info));
        }

        /// <summary>
        /// 接口请求信息(记录信息)
        /// </summary>
        /// <param name="msg">信息</param>
        public static void RequestInfo(string msg)
        {
            string isOpenRequestLog = ConfigurationManager.AppSettings["OpenRequestLog"].ToString();
            if ("true".Equals(isOpenRequestLog))
            {
                Task.Run(() => WriteLog(null, msg, LogEnum.Request));
            }
        }

        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="exception">异常信息</param>
        /// <param name="otherMsg">其他信息</param>
        /// <param name="logType">日志类型</param>
        private static void WriteLog(Exception exception, string otherMsg, LogEnum logType)
        {
            string str = "";
            try
            {
                str += string.Format(@"
DateTime:{0}", DateTime.Now.ToString());
                if (exception != null)
                {
                    if (exception.InnerException != null)
                    {
                        exception = exception.InnerException;
                    }
                    str += string.Format(@"
Message:{0}
StackTrace:
{1}
Source:{2}
"
 , exception.Message
 , exception.StackTrace
 , exception.Source

                    );
                }
                str += string.Format(@"
ExtMessage:{0}", otherMsg);
                string filePath = "";
                object lockObj = new object();
                switch (logType)
                {
                    case LogEnum.Error:
                        filePath = Path.Combine(logDir, DateTime.Now.ToString("yyyyMMdd") + ".txt");
                        lockObj = objError;
                        break;
                    case LogEnum.Info:
                        filePath = Path.Combine(infoLogDir, DateTime.Now.ToString("yyyyMMdd") + ".txt");
                        lockObj = objInfo;
                        break;
                    case LogEnum.Request:
                        filePath = Path.Combine(requestLogDir, DateTime.Now.ToString("yyyyMMdd") + ".txt");
                        lockObj = objRequest;
                        break;
                }
                lock (lockObj)
                {
                    StreamWriter sw = new StreamWriter(filePath, true);
                    sw.WriteLine(str);
                    sw.Close();
                }
            }
            catch
            {

            }
        }
    }
    /// <summary>
    /// 日志枚举
    /// </summary>
    public enum LogEnum
    {
        /// <summary>
        /// 错误日志
        /// </summary>
        Error = 1,
        /// <summary>
        /// 信息记录
        /// </summary>
        Info = 2,
        /// <summary>
        /// 接口请求
        /// </summary>
        Request = 3
    }
}
