using System;
using Quadarax.Foundation.Core.Console;

namespace Quadarax.Foundation.Core.Logging
{
    public class ConsoleLog : ILog
    {
        private readonly string _typeName;
        private readonly LogSeverityEnum[]? _excludeSeverities;

		private readonly ConsoleWriter _infoWriter = new ConsoleWriter(ConsoleColor.White);
        private readonly ConsoleWriter _debugWriter = new ConsoleWriter(ConsoleColor.Green);
        private readonly ConsoleWriter _warnWriter = new ConsoleWriter(ConsoleColor.Yellow);
        private readonly ConsoleWriter _errorWriter = new ConsoleWriter(ConsoleColor.Red);
        private ConsoleWriter _traceWriter = new ConsoleWriter(ConsoleColor.DarkGray);
        public ConsoleLog(Type owningType, LogSeverityEnum[]? excludedSeverities = null) : this(owningType.Name, excludedSeverities)
        {
        }

        public ConsoleLog(string owningTypeName, LogSeverityEnum[]? excludedSeverities = null)
        {
            _typeName = owningTypeName;
            _excludeSeverities = excludedSeverities;
        }

        public void Log(LogSeverityEnum severity, int code, string message)
        {
			Log(severity, $"Code:{code}, {message}");            
        }

        public void Log(LogSeverityEnum severity, string message)
        {
            if (_excludeSeverities != null && Array.IndexOf(_excludeSeverities, severity) >= 0)
                return;

            var now = DateTime.Now;
            var thNum = System.Threading.Thread.CurrentThread.ManagedThreadId;

            var final = $"[{severity}:{now.ToLongTimeString()}:{thNum}]#{_typeName}: {message}";

            switch (severity)
            {
                case LogSeverityEnum.Info:
                    _infoWriter.WriteLine(final);
                    break;
                case LogSeverityEnum.Debug:
                    _debugWriter.WriteLine(final);
                    break;
                case LogSeverityEnum.Warn:
                    _warnWriter.WriteLine(final);
                    break;
                case LogSeverityEnum.Fatal:
                case LogSeverityEnum.Error:
                    _errorWriter.WriteLine(final);
                    break;
            }
        }

        public void Log(LogSeverityEnum severity, string message, Exception? exception)
        {
            Log(severity, $"{message}\n{exception}");
        }

        public void Log(LogSeverityEnum severity, int code, string message, Exception? exception)
        {
            Log(severity, string.Format("{2} - {0}\n{1}", message,exception, code));
        }
    }
}
