using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;

namespace System.Web.Mvc
{
    public class MvcLog
    {
        static object mvc_writelock = new object();
        /// <summary>
        /// 日志文件夹
        /// </summary>
        public static string MvcLogFolder { get; set; }
        /// <summary>
        /// 日志路径
        /// </summary>
        /// <returns></returns>
        private static string GetPath(string filename = null)
        {
            if (string.IsNullOrEmpty(filename) == true)
                filename = "未处理异常_" + DateTime.Now.ToString("yyyy-MM-dd") + ".log";

            string folder = MvcLogFolder;
            if (folder == null)
            {
                folder = string.Empty;
            }
            if (folder.EndsWith("\\") != true)
            {
                folder += "\\";
            }

            string root = folder + filename;
            string dic = System.IO.Path.GetDirectoryName(root);

            if (System.IO.Directory.Exists(dic) != true)
            {
                System.IO.Directory.CreateDirectory(dic);
            }
            return root;
        }
        /// <summary>
        /// 将指定字符串中的格式项替换为指定数组中相应对象的字符串表示形式。
        /// </summary>
        /// <param name="format"> 复合格式字符串。</param>
        /// <param name="args">一个对象数组，其中包含零个或多个要设置格式的对象。</param>
        public static void Write(string format, params object[] args)
        {
            System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback((obj) =>
            {
                lock (mvc_writelock)
                {
                    LogModel lm = obj as LogModel;
                    try
                    {
                        string value = string.Empty;
                        if (lm.format.Contains("{0}") == true && lm.args != null && lm.args.Length > 0)
                            value = string.Format(lm.format, lm.args);
                        else
                            value = lm.format;
                        System.IO.File.AppendAllText(GetPath(),
                            string.Format("{0}   [日志内容:{1}]{2}", DateTime.Now, value, Environment.NewLine));
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("写mvc异常失败:" + ex.Message);
                    }
                }
            }), new LogModel(format, args));
        }
        /// <summary>
        /// 将指定字符串中的格式项替换为指定数组中相应对象的字符串表示形式。
        /// </summary>
        /// <param name="format"> 复合格式字符串。</param>
        /// <param name="args">一个对象数组，其中包含零个或多个要设置格式的对象。</param>
        public static void WriteRequestLog(string format, params object[] args)
        {
            System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback((obj) =>
            {
                lock (mvc_writelock)
                {
                    LogModel lm = obj as LogModel;
                    try
                    {
                        string value = string.Empty;
                        if (lm.format.Contains("{0}") == true && lm.args != null && lm.args.Length > 0)
                            value = string.Format(lm.format, lm.args);
                        else
                            value = lm.format;
                        System.IO.File.AppendAllText(GetPath(string.Format("Time%/{0}/请求-响应_{1}.csv", DateTime.Now.ToString("yyyyMMdd"), DateTime.Now.ToString("HH"))),
                            string.Format("{0}   [日志内容:{1}]{2}", DateTime.Now, value, Environment.NewLine));
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("写mvc异常失败:" + ex.Message);
                    }
                }
            }), new LogModel(format, args));
        }

        class LogModel
        {
            public LogModel(string format, params object[] args)
            {
                this.format = format;
                this.args = args;
            }
            public string format { get; set; }
            public object[] args { get; set; }
        }
    }
}