using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FileManager
{
    public class LogManager
    {
        #region 定义属性
        private static string filePath = string.Empty;
        /// <summary>
        /// 存储路径
        /// </summary>
        protected static string FilePath { get => filePath; set => filePath = value; }
        /// <summary>
        /// 运行状态
        /// </summary>
        private static bool runState = false;
        protected static bool RunState { get => runState; set => runState = value; }
        /// <summary>
        /// 日志名称，按照当前时间生成
        /// </summary>
        protected string LogName { get => logName; set => logName = value; }
        /// <summary>
        /// 硬件日志文件路径
        /// </summary>
        protected static string HardwareLogPath { get => hardwareLogPath; set => hardwareLogPath = value; }

        //默认日志路径
        private static string defaultPath = @"\Log\";
        //硬件日志文件路径
        private static string hardwareLogPath = string.Empty;
        //硬件日志名称
        private static string logName = string.Empty;
        #endregion

        #region 初始化创建日志文件
        /// <summary>
        /// 初始化日志文件,如不存在根据xml路径创建
        /// </summary>
        /// <param name="xmlFilePath">xml存储位置</param>
        public static void Init(string xmlFilePath)
        {
            CreateFile(xmlFilePath);
        }

        /// <summary>
        /// 初始化记录硬件操作日志文件,默认创建日志文件
        /// </summary>
        public static void InitManulLog()
        {
            //硬件日志名称
            logName = DateTime.Now.ToString("yyyyMMddHHmmss") + "ManulLog.txt";
            CreateHardwareFile(logName);
        }

        /// <summary>
        /// 初始化记录硬件操作日志文件,默认创建日志文件
        /// </summary>
        public static void InitHardwareLog()
        {
            //硬件日志名称
            logName = DateTime.Now.ToString("yyyyMMddHHmmss")+ "HardwareLog.txt";
            CreateHardwareFile(logName);
        }
        #endregion

        #region 添加记录日志
        /// <summary>
        /// 记录运行日志
        /// </summary>
        /// <param name="logContent">日志运行内容</param>
        public static void LogTrace(string logContent)
        {
            //获取调用当前方法的页面与代码行数
            StackTrace st = new StackTrace(new StackFrame(1, true));
            StackFrame sf = st.GetFrame(0);
            //文件名称
            string FileName = sf.GetFileName();
            //方法名
            string MethodName = sf.GetMethod().Name;
            //行号
            int LineNumber = sf.GetFileLineNumber();
            //设置运行状态
            RunState = true;
            st = null;
            
            LogWrite(FileName, MethodName, LineNumber, logContent, RunState);
        }
        /// <summary>
        /// 记录错误日志
        /// </summary>
        /// <param name="logErrorContent">日志错误内容</param>
        public static void LogError(string logErrorContent)
        {
            //获取调用当前方法的页面与代码行数
            StackTrace st = new StackTrace(new StackFrame(1, true));
            StackFrame sf = st.GetFrame(0);
            //文件名称
            string FileName = sf.GetFileName();
            //方法名
            string MethodName = sf.GetMethod().Name;
            //行号
            int LineNumber = sf.GetFileLineNumber();
            //设置运行状态
            RunState = false;
            st = null;
            LogWrite(FileName, MethodName, LineNumber, logErrorContent, RunState);
        }

        /// <summary>
        /// 添加硬件运行日志
        /// </summary>
        /// <param name="logContent">日志内容</param>
        /// <param name="logState">True:正常日志 False:错误日志</param>
        public static void AddHardwareLog(string logContent,bool logState)
        {
            //获取调用当前方法的页面与代码行数
            StackTrace st = new StackTrace(new StackFrame(1, true));
            StackFrame sf = st.GetFrame(0);
            //文件名称
            string FileName = sf.GetFileName();
            //方法名
            string MethodName = sf.GetMethod().Name;
            //行号
            int LineNumber = sf.GetFileLineNumber();
            ////设置运行状态
            //RunState = true;
            st = null;

            HardwareLogWrite(FileName, MethodName, LineNumber, logContent, logState);
        }
        #endregion

        #region 读取日志信息 返回DataTable
        /// <summary>
        /// 读取日志信息 返回DataTable
        /// </summary>
        /// <param name="xmlFilePath">xml路径</param>
        /// <returns>返回DataTable</returns>
        public static DataTable LogRead(string xmlFilePath)
        {
            try
            {
                if (xmlFilePath.Equals(""))
                {
                    return null;
                }
                int lastIndex = xmlFilePath.LastIndexOf(@"/");
                string path = xmlFilePath.Substring(0, lastIndex);
                //设置测量文件的路径
                FilePath = path + @"/log.txt";
                //读取日志信息
                FileStream fsRead = new FileStream(FilePath, FileMode.Open, FileAccess.Read);//创建写入文件    
                int fsLen = (int)fsRead.Length;
                byte[] heByte = new byte[fsLen];
                int r = fsRead.Read(heByte, 0, heByte.Length);
                //将信息转换为字符串
                string logStr = System.Text.Encoding.UTF8.GetString(heByte);
                fsRead.Close();
                DataTable dt = CreateDataSource(logStr);
                return dt;
            }
            catch (Exception)
            {
                return null;
            }
        }
        /// <summary>
        /// 根据日志内容创建数据源
        /// </summary>
        /// <param name="logStr"></param>
        /// <returns></returns>
        protected static DataTable CreateDataSource(string logStr)
        {
            //拆分为字符组
            string[] groupStr = logStr.Split('\n');
            //创建数据源
            DataTable dt = new DataTable();
            dt.Columns.Add("切入点名称");
            dt.Columns.Add("步骤名称");
            dt.Columns.Add("完成时间");
            dt.Columns.Add("状态");
            foreach (string item in groupStr)
            {
                if (!item.Equals(""))
                {
                    DataRow dataRow = dt.NewRow();
                    //将每个字符组拆分为对应的信息
                    string[] eleStr = item.Split('-');
                    //切入点名称与步骤信息
                    string[] strNameCotent = eleStr[5].Split(':');
                    if (strNameCotent.Length > 1)
                    {
                        dataRow[0] = strNameCotent[0];
                        dataRow[1] = strNameCotent[1];
                    }
                    else
                    {
                        dataRow[0] = eleStr[5];
                        dataRow[1] = eleStr[5];
                    }
                    dataRow[2] = eleStr[4];
                    dataRow[3] = eleStr[6];
                    dt.Rows.Add(dataRow);
                }
            }
            return dt;
        }
        #endregion
        
        #region 日志文件类操作
        /// <summary>
        /// 创建日志文件
        /// </summary>
        protected static bool CreateFile(string xmlFilePath)
        {
            if (xmlFilePath.Equals(""))
            {
                return false;
            }
            //拆分xml路径
            int lastIndex = xmlFilePath.LastIndexOf(@"/");
            string path = xmlFilePath.Substring(0, lastIndex);
            //设置日志文件的路径
            FilePath = path+@"/log.txt";
            //判断是否存在日志路径
            if (!IsExistFile(filePath))
            {
                //没有则创建这个文件
                FileStream fs1 = new FileStream(filePath, FileMode.Create, FileAccess.Write);
                fs1.Close();
                return true;
            }
            return false;
        }

        protected static bool CreateHardwareFile(string logName)
        {
            string DirectoryPath = Application.StartupPath + defaultPath;
            if (!Directory.Exists(DirectoryPath))
            {
                Directory.CreateDirectory(DirectoryPath);
            }
            HardwareLogPath = DirectoryPath + logName;
            //判断是否存在日志路径
            if (!IsExistFile(HardwareLogPath))
            {
                //没有则创建这个文件
                FileStream fs1 = new FileStream(HardwareLogPath, FileMode.Create, FileAccess.Write);
                fs1.Close();
                return true;
            }
            return false;
        }
        /// <summary>
        /// 判断是否存在日志文件
        /// </summary>
        protected static bool IsExistFile(string filePath)
        {
            if (File.Exists(filePath))
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 写日志
        /// </summary>
        protected static void LogWrite(string FileName, string MethodName, int LineNumber, string logContent,bool logState)
        {
            try
            {
                //记录日志时间
                string currTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
                //格式:(日志类型+日志记录的所在文件名称+方法名称+行号+时间+描述+状态)
                string logType = "Trace";
                if (!logState)
                {
                    logType = "Error";
                }
                //日志类型：LogType:Trace 文件名：xxxx.cs 方法名：aaa() 行数：10 时间：2020-XX-XX XX:XX:XX 描述：切点名称-操作描述 状态：True 
                string logStr = "LogType:" + logType + "-" + FileName + "-" + MethodName + "-" + LineNumber + "-" + currTime + "-" + logContent + "-" + logState.ToString() + "";
                //写入日志信息
                FileStream fs1 = new FileStream(filePath, FileMode.Append, FileAccess.Write);//创建写入文件    
                StreamWriter sw = new StreamWriter(fs1);
                sw.WriteLine(logStr);//开始写入值
                sw.Close();
                fs1.Close();
            }
            catch (Exception)
            {
                return;
            }
        }

        protected static void HardwareLogWrite(string FileName, string MethodName, int LineNumber, string logContent, bool logState)
        {
            try
            {
                //记录日志时间
                string currTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
                //格式:(日志类型+日志记录的所在文件名称+方法名称+行号+时间+描述+状态)
                string logType = "Trace";
                if (!logState)
                {
                    logType = "Error";
                }
                //日志类型：LogType:Trace 文件名：xxxx.cs 方法名：aaa() 行数：10 时间：2020-XX-XX XX:XX:XX 描述：切点名称-操作描述 状态：True 
                string logStr = "LogType:" + logType + "-" + FileName + "-" + MethodName + "-" + LineNumber + "-" + currTime + "-" + logContent + "-" + logState.ToString() + "";
                //写入日志信息
                FileStream fs1 = new FileStream(HardwareLogPath, FileMode.Append, FileAccess.Write);//创建写入文件    
                StreamWriter sw = new StreamWriter(fs1);
                sw.WriteLine(logStr);//开始写入值
                sw.Close();
                fs1.Close();
            }
            catch (Exception)
            {
                return;
            }
        }
        #endregion

    }
}
