using System;
using System.Diagnostics;
using RebootKit.Engine.Main;

namespace RebootKit.Engine.Foundation {
    public enum LogLevel {
        Info,
        Debug,
        Warning,
        Error
    }

    public readonly struct Logger {
        readonly string m_Name;

        public Logger(string name) {
            m_Name = name;
        }

        public void Log(LogLevel level, string message) {
            switch (level) {
                case LogLevel.Info:
                    RR.Log(FormatMessage(level, m_Name, message, true));
                    break;
                case LogLevel.Debug:
                    RR.Log(FormatMessage(level, m_Name, message, true));
                    break;
                case LogLevel.Warning:
                    RR.LogWarning(FormatMessage(level, m_Name, message, true));
                    break;
                case LogLevel.Error:
                    RR.LogError(FormatMessage(level, m_Name, message, true));
                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(level), level, null);
            }
        }

        [Conditional(RConsts.k_BuildFlagDebug)]
        public void Info(string message) {
            Log(LogLevel.Info, message);
        }

        [Conditional(RConsts.k_BuildFlagDebug)]
        public void Debug(string message) {
            Log(LogLevel.Debug, message);
        }

        [Conditional(RConsts.k_BuildFlagDebug)]
        public void Warning(string message) {
            Log(LogLevel.Warning, message);
        }

        public void Error(string message) {
            Log(LogLevel.Error, message);
        }

        static string FormatMessage(LogLevel level, string name, string message, bool richText) {
            if (!richText) {
                string prefix = level switch {
                    LogLevel.Info => "",
                    LogLevel.Debug => "[DEBUG]",
                    LogLevel.Warning => "[WARNING]",
                    LogLevel.Error => "[ERROR]",
                    _ => throw new ArgumentOutOfRangeException(nameof(level), level, null)
                };
                return $"{prefix}[{name}] {message}";
            }

            switch (level) {
                case LogLevel.Info:
                    return $"[<b>{name}</b>] {message}";
                case LogLevel.Debug:
                    return $"[D][<b>{name}</b>] <color=#ffffff>{message}</color>";
                case LogLevel.Warning:
                    return $"[W][<b>{name}</b>] <color=#ffffff>{message}</color>";
                case LogLevel.Error:
                    return $"[<b><color=#e83f25>ERROR</color></b>][<b>{name}</b>] <color=#ffffff>{message}</color>";
                default:
                    throw new ArgumentOutOfRangeException(nameof(level), level, null);
            }
        }
    }
}