using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace AdvertsingProfitControl
{
    internal class Logger
    {
        public static string LogFolderPath = Path.GetPathRoot(Environment.SystemDirectory) + @"Users\" + Environment.UserName + @"\AppData\Local\APC\";

        /// <summary>
        /// 
        /// </summary>
        /// <param name="date">Date and time of the event.</param>
        /// <param name="source">The class or form name that generated the message.</param>
        /// <param name="message">Log message.</param>
        /// <param name="level">The log's level.</param>
        /// <returns>A Log object to optionally store for later use by the calling code.</returns>
        public static Log WriteLog(DateTime date, string source, string message, Level level)
        {
            var log = new Log
            {
                Date = date,
                Level = level,
                Message = message,
                Source = source
            };
            //Check to see if the message level is a critical (0) error. 
            //If it is not then simply return the Log object to the calling code.
            if (level == Level.Critical)
            {
                //If the message is critical then write it to disk and return the Log object created.
                using (var file = new StreamWriter(LogFolderPath + DateTime.Now.ToString("yy-MM-dd") + ".log", true))
                {
                    file.WriteLine(SerializeLog(log));
                }
            }
            else
            {
                using (var file = new StreamWriter(LogFolderPath + "information.log", true))
                {
                    file.WriteLine(SerializeLog(log));
                }
            }
            return log;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="logFilePath"></param>
        /// <returns></returns>
        public List<Log> ReadLogFile(string logFilePath = null)
        {
            var logs = new List<Log>();
            //Check to see if a specific log file has been passed in.
            if (logFilePath == null)
            {
                //If no specific log file has been passed then check to see if the
                //default information log exists. 
                if (!File.Exists(LogFolderPath + "information.log"))
                {
                    //If it doesn't then return an empty list.
                    return logs;
                }
                logFilePath = LogFolderPath + "information.log";
            }

            var myDeserializer = new XmlSerializer(typeof(List<Log>));
            var myFileStream = new FileStream(logFilePath, FileMode.Open);
            var stream = new StreamReader(myFileStream, Encoding.UTF8);
            logs = (List<Log>)myDeserializer.Deserialize(stream);
            myFileStream.Close();

            return logs;
        }

        private static string SerializeLog(Log log)
        {
            var serializer = new XmlSerializer(typeof(Log));
            string xml;

            using (var sw = new StringWriter())
            {
                using (var writer = new XmlTextWriter(sw) {Formatting = Formatting.Indented})
                {
                    writer.WriteStartElement("Log");
                    writer.WriteElementString("Date", log.Date.ToString("g"));
                    writer.WriteElementString("Level", log.Level.ToString());
                    writer.WriteElementString("Source", log.Source);
                    writer.WriteElementString("Message", log.Message);
                    writer.Close();
                    //serializer.Serialize(writer, log);
                    xml = sw.ToString();
                }
            }

            return xml;
        }
    }
}
