using NLog;
using Sentry;
using System;

namespace HRD.AppLogger
{
    public class LoggerManager : ILoggerManager
    {
        private static readonly ILogger logger = LogManager.GetCurrentClassLogger();

        public LoggerManager(bool throwExceptions = true) : this()
        {
            LogManager.ThrowExceptions = throwExceptions;
        }

        public LoggerManager()
        {
            GlobalDiagnosticsContext.Set("Version", AppLoggerConfig.AssemblyVersion);
            GlobalDiagnosticsContext.Set("Application", AppLoggerConfig.AssemblyName);

            LogManager.ThrowConfigExceptions = true;
            LogManager.ThrowExceptions = false;
            LogManager.Configuration = AppLoggerConfig.CreateConfig();
        }

        public void WriteLog(Action<Object> log, Object message, string entityMessage = null, string webrequest = null, string userLogin = null)
        {
            MappedDiagnosticsLogicalContext.Set("Entity", !String.IsNullOrEmpty(entityMessage) ? entityMessage : "");
            MappedDiagnosticsLogicalContext.Set("Webrequest", !String.IsNullOrEmpty(webrequest) ? webrequest : "");

            if (AppLoggerConfig.NlogSentryConfig.NlogSentryIsEnable)
            {
                SentrySdk.WithScope(scope =>
                {
                    if (!String.IsNullOrEmpty(entityMessage))
                    {
                        scope.SetTag("Entity", entityMessage);
                    }

                    if (!String.IsNullOrEmpty(webrequest))
                    {
                        scope.SetTag("Webrequest", webrequest);
                    }

                    if (!String.IsNullOrEmpty(userLogin))
                    {
                        scope.SetTag("UserLogin", userLogin);
                    }

                    log(message);
                });
            }
            else log(message);
        }

        public void LogDebug(string message, string entityMessage = null, string webrequest = null, string userLogin = null)
        {
            WriteLog(logger.Debug, message, entityMessage, webrequest, userLogin);

            /*            MappedDiagnosticsLogicalContext.Set("Entity", !String.IsNullOrEmpty(entityMessage) ? entityMessage : "");
                        MappedDiagnosticsLogicalContext.Set("Webrequest", !String.IsNullOrEmpty(webrequest) ? webrequest : "");

                        if (AppLoggerConfig.NlogSentryConfig.NlogSentryIsEnable)
                        {
                            SentrySdk.WithScope(scope =>
                            {
                                if (!String.IsNullOrEmpty(entityMessage))
                                {
                                    scope.SetTag("Entity", entityMessage);
                                }

                                if (!String.IsNullOrEmpty(webrequest))
                                {
                                    scope.SetTag("Webrequest", webrequest);
                                }

                                if (!String.IsNullOrEmpty(userLogin))
                                {
                                    scope.SetTag("UserLogin", userLogin);
                                }

                                logger.Debug(message);
                            });
                        }
                        else logger.Debug(message);*/
        }

        public void LogError(string message, string entityMessage = null, string webrequest = null, string userLogin = null)
        {
            //WriteLog(logger.Error, message, entityMessage, webrequest, userLogin);
            MappedDiagnosticsLogicalContext.Set("Entity", !String.IsNullOrEmpty(entityMessage) ? entityMessage : "");
            MappedDiagnosticsLogicalContext.Set("Webrequest", !String.IsNullOrEmpty(webrequest) ? webrequest : "");

            if (AppLoggerConfig.NlogSentryConfig.NlogSentryIsEnable)
            {
                SentrySdk.WithScope(scope =>
                {
                    if (!String.IsNullOrEmpty(entityMessage))
                    {
                        scope.SetTag("Entity", entityMessage);
                    }

                    if (!String.IsNullOrEmpty(webrequest))
                    {
                        scope.SetTag("Webrequest", webrequest);
                    }

                    if (!String.IsNullOrEmpty(userLogin))
                    {
                        scope.SetTag("UserLogin", userLogin);
                    }

                    logger.Error(message);
                });
            }
            else logger.Error(message);
        }

        public void LogException(Exception exception, string entityMessage = null, string webrequest = null, string userLogin = null)
        {
            //WriteLog(logger.Error, exception, entityMessage, webrequest, userLogin);

            MappedDiagnosticsLogicalContext.Set("Entity", !String.IsNullOrEmpty(entityMessage) ? entityMessage : "");
            MappedDiagnosticsLogicalContext.Set("Webrequest", !String.IsNullOrEmpty(webrequest) ? webrequest : "");

            if (AppLoggerConfig.NlogSentryConfig.NlogSentryIsEnable)
            {
                SentrySdk.WithScope(scope =>
                {
                    if (!String.IsNullOrEmpty(entityMessage))
                    {
                        scope.SetTag("Entity", entityMessage);
                    }

                    if (!String.IsNullOrEmpty(webrequest))
                    {
                        scope.SetTag("Webrequest", webrequest);
                    }

                    if (!String.IsNullOrEmpty(userLogin))
                    {
                        scope.SetTag("UserLogin", userLogin);
                    }

                    logger.Error(exception);
                });
            }
            else logger.Error(exception);
        }

        public void LogWarn(string message, string entityMessage = null, string webrequest = null, string userLogin = null)
        {
            //WriteLog(logger.Warn, message, entityMessage, webrequest, userLogin);

            MappedDiagnosticsLogicalContext.Set("Entity", !String.IsNullOrEmpty(entityMessage) ? entityMessage : "");
            MappedDiagnosticsLogicalContext.Set("Webrequest", !String.IsNullOrEmpty(webrequest) ? webrequest : "");

            if (AppLoggerConfig.NlogSentryConfig.NlogSentryIsEnable)
            {
                SentrySdk.WithScope(scope =>
                {
                    if (!String.IsNullOrEmpty(entityMessage))
                    {
                        scope.SetTag("Entity", entityMessage);
                    }

                    if (!String.IsNullOrEmpty(webrequest))
                    {
                        scope.SetTag("Webrequest", webrequest);
                    }

                    if (!String.IsNullOrEmpty(userLogin))
                    {
                        scope.SetTag("UserLogin", userLogin);
                    }

                    logger.Warn(message);
                });
            }
            else logger.Warn(message);
        }

        public void LogInfo(string message, string entityMessage = null, string webrequest = null, string userLogin = null)
        {
            //WriteLog(logger.Info, message, entityMessage, webrequest, userLogin);
            MappedDiagnosticsLogicalContext.Set("Entity", !String.IsNullOrEmpty(entityMessage) ? entityMessage : "");
            MappedDiagnosticsLogicalContext.Set("Webrequest", !String.IsNullOrEmpty(webrequest) ? webrequest : "");

            if (AppLoggerConfig.NlogSentryConfig.NlogSentryIsEnable)
            {
                SentrySdk.WithScope(scope =>
                {
                    if (!String.IsNullOrEmpty(entityMessage))
                    {
                        scope.SetTag("Entity", entityMessage);
                    }

                    if (!String.IsNullOrEmpty(webrequest))
                    {
                        scope.SetTag("Webrequest", webrequest);
                    }

                    if (!String.IsNullOrEmpty(userLogin))
                    {
                        scope.SetTag("UserLogin", userLogin);
                    }

                    logger.Info(message);
                });
            }
            else logger.Info(message);
        }
    }
}