using System;

namespace NT8.Core.Logging
{
    /// <summary>
    /// Log severity levels.
    /// </summary>
    public enum LogLevel
    {
        Debug = 0,
        Information = 1,
        Warning = 2,
        Error = 3,
        Critical = 4
    }

    /// <summary>
    /// Basic console logger implementation for .NET Framework 4.8
    /// </summary>
    public class BasicLogger : ILogger
    {
        private readonly string _categoryName;

        /// <summary>
        /// Minimum log level to write. Messages below this level are suppressed.
        /// Default is Information.
        /// </summary>
        public LogLevel MinimumLevel { get; set; }

        public BasicLogger(string categoryName = "")
        {
            _categoryName = categoryName;
            MinimumLevel = LogLevel.Information;
        }

        public void LogDebug(string message, params object[] args)
        {
            WriteLog(LogLevel.Debug, "DEBUG", message, args);
        }

        public void LogInformation(string message, params object[] args)
        {
            WriteLog(LogLevel.Information, "INFO", message, args);
        }

        public void LogWarning(string message, params object[] args)
        {
            WriteLog(LogLevel.Warning, "WARN", message, args);
        }

        public void LogError(string message, params object[] args)
        {
            WriteLog(LogLevel.Error, "ERROR", message, args);
        }

        public void LogCritical(string message, params object[] args)
        {
            WriteLog(LogLevel.Critical, "CRITICAL", message, args);
        }

        private void WriteLog(LogLevel level, string levelLabel, string message, params object[] args)
        {
            if (level < MinimumLevel)
                return;

            var timestamp = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff");
            var formattedMessage = args.Length > 0 ? String.Format(message, args) : message;
            var category = !String.IsNullOrEmpty(_categoryName) ? String.Format("[{0}] ", _categoryName) : "";

            Console.WriteLine(String.Format("{0} [{1}] {2}{3}", timestamp, levelLabel, category, formattedMessage));
        }
    }
}
