﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="FileLoggerHandler.cs" company="Fox Council">
//   Fox Council
// </copyright>
// <summary>
//   The file logger handler.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace MineAPI.EditorBase.Logging.Handlers
{
    using System;
    using System.IO;

    using Formatters;

    /// <summary>
    /// The file logger handler.
    /// </summary>
    public class FileLoggerHandler : ILoggerHandler
    {
        #region Fields

        /// <summary>
        /// The _directory.
        /// </summary>
        private readonly string _directory;

        /// <summary>
        /// The _file name.
        /// </summary>
        private readonly string _fileName;

        /// <summary>
        /// The _logger formatter.
        /// </summary>
        private readonly ILoggerFormatter _loggerFormatter;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="FileLoggerHandler"/> class.
        /// </summary>
        public FileLoggerHandler()
            : this(CreateFileName())
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FileLoggerHandler"/> class.
        /// </summary>
        /// <param name="fileName">
        /// The file name.
        /// </param>
        public FileLoggerHandler(string fileName)
            : this(fileName, string.Empty)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FileLoggerHandler"/> class.
        /// </summary>
        /// <param name="fileName">
        /// The file name.
        /// </param>
        /// <param name="directory">
        /// The directory.
        /// </param>
        public FileLoggerHandler(string fileName, string directory)
            : this(new DefaultLoggerFormatter(), fileName, directory)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FileLoggerHandler"/> class.
        /// </summary>
        /// <param name="loggerFormatter">
        /// The logger formatter.
        /// </param>
        public FileLoggerHandler(ILoggerFormatter loggerFormatter)
            : this(loggerFormatter, CreateFileName())
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FileLoggerHandler"/> class.
        /// </summary>
        /// <param name="loggerFormatter">
        /// The logger formatter.
        /// </param>
        /// <param name="fileName">
        /// The file name.
        /// </param>
        public FileLoggerHandler(ILoggerFormatter loggerFormatter, string fileName)
            : this(loggerFormatter, fileName, string.Empty)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FileLoggerHandler"/> class.
        /// </summary>
        /// <param name="loggerFormatter">
        /// The logger formatter.
        /// </param>
        /// <param name="fileName">
        /// The file name.
        /// </param>
        /// <param name="directory">
        /// The directory.
        /// </param>
        public FileLoggerHandler(ILoggerFormatter loggerFormatter, string fileName, string directory)
        {
            _loggerFormatter = loggerFormatter;
            _fileName = fileName;
            _directory = directory;
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// The publish.
        /// </summary>
        /// <param name="logMessage">
        /// The log message.
        /// </param>
        public void Publish(LogMessage logMessage)
        {
            if (!string.IsNullOrEmpty(_directory))
            {
                var directoryInfo = new DirectoryInfo(Path.Combine(_directory));
                if (!directoryInfo.Exists)
                {
                    directoryInfo.Create();
                }
            }

            using (var writer = new StreamWriter(File.Open(Path.Combine(_directory, _fileName), FileMode.Append))) writer.WriteLine(_loggerFormatter.ApplyFormat(logMessage));
        }

        #endregion

        #region Methods

        /// <summary>
        /// The create file name.
        /// </summary>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        private static string CreateFileName()
        {
            var currentDate = DateTime.Now;
            var guid = Guid.NewGuid();
            return string.Format(
                "Log_{0:0000}{1:00}{2:00}-{3:00}{4:00}_{5}.log", 
                currentDate.Year, 
                currentDate.Month, 
                currentDate.Day, 
                currentDate.Hour, 
                currentDate.Minute, 
                guid);
        }

        #endregion
    }
}