using System;
using System.ComponentModel;
using Alibabacloud.Rum.Unity.Logs;

namespace Alibabacloud.Rum.Unity.Logs
{
    /// <summary>
    /// The generic overloads avoid boxing in case logging is disabled for that level
    /// </summary>
    /// <remarks>
    /// Calls to this class verify the level before calling the overload with object params.
    /// </remarks>
    [EditorBrowsable(EditorBrowsableState.Never)]
    public static class DiagnosticLoggerExtensions
    {
        /// <summary>
        /// Log an internal SDK message.
        /// </summary>
        public static void Log(
            this AlibabacloudOptions options,
            AlibabacloudLogLevel logLevel,
            string message,
            Exception? exception = null,
            params object?[] args)
            => options?.DiagnosticLogger?.Log(logLevel, message, exception, args);

        /// <summary>
        /// Log a debug message.
        /// </summary>
        public static void LogDebug<TArg>(
            this IDiagnosticLogger logger,
            string message,
            TArg arg)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Debug, null, message, arg);

        /// <summary>
        /// Log a debug message.
        /// </summary>
        public static void LogDebug<TArg>(
            this AlibabacloudOptions options,
            string message,
            TArg arg)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Debug, null, message, arg);

        /// <summary>
        /// Log a debug message.
        /// </summary>
        public static void LogDebug<TArg, TArg2>(
            this IDiagnosticLogger logger,
            string message,
            TArg arg,
            TArg2 arg2)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Debug, null, message, arg, arg2);

        /// <summary>
        /// Log a debug message.
        /// </summary>
        public static void LogDebug<TArg, TArg2>(
            this AlibabacloudOptions options,
            string message,
            TArg arg,
            TArg2 arg2)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Debug, null, message, arg, arg2);

        /// <summary>
        /// Log a debug message.
        /// </summary>
        public static void LogDebug<TArg, TArg2, TArg3>(
            this IDiagnosticLogger logger,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Debug, null, message, arg, arg2, arg3);

        /// <summary>
        /// Log a debug message.
        /// </summary>
        public static void LogDebug<TArg, TArg2, TArg3>(
            this AlibabacloudOptions options,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Debug, null, message, arg, arg2, arg3);

        /// <summary>
        /// Log a debug message.
        /// </summary>
        public static void LogDebug(
            this IDiagnosticLogger logger,
            string message)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Debug, null, message);

        /// <summary>
        /// Log a debug message.
        /// </summary>
        public static void LogDebug(
            this AlibabacloudOptions options,
            string message)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Debug, null, message);

        /// <summary>
        /// Log a info message.
        /// </summary>
        public static void LogInfo(
            this IDiagnosticLogger logger,
            string message)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Info, null, message);

        /// <summary>
        /// Log a info message.
        /// </summary>
        public static void LogInfo(
            this AlibabacloudOptions options,
            string message)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Info, null, message);

        /// <summary>
        /// Log a info message.
        /// </summary>
        public static void LogInfo<TArg>(
            this IDiagnosticLogger logger,
            string message,
            TArg arg)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Info, null, message, arg);

        /// <summary>
        /// Log a info message.
        /// </summary>
        public static void LogInfo<TArg>(
            this AlibabacloudOptions options,
            string message,
            TArg arg)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Info, null, message, arg);

        /// <summary>
        /// Log a info message.
        /// </summary>
        public static void LogInfo<TArg, TArg2>(
            this IDiagnosticLogger logger,
            string message,
            TArg arg,
            TArg2 arg2)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Info, null, message, arg, arg2);

        /// <summary>
        /// Log a info message.
        /// </summary>
        public static void LogInfo<TArg, TArg2>(
            this AlibabacloudOptions options,
            string message,
            TArg arg,
            TArg2 arg2)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Info, null, message, arg, arg2);

        /// <summary>
        /// Log a info message.
        /// </summary>
        public static void LogInfo<TArg, TArg2, TArg3>(
            this IDiagnosticLogger logger,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Info, null, message, arg, arg2, arg3);

        /// <summary>
        /// Log a info message.
        /// </summary>
        public static void LogInfo<TArg, TArg2, TArg3>(
            this AlibabacloudOptions options,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Info, null, message, arg, arg2, arg3);

        /// <summary>
        /// Log a warning message.
        /// </summary>
        public static void LogWarning(
            this IDiagnosticLogger logger,
            string message)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Warning, null, message);

        /// <summary>
        /// Log a warning message.
        /// </summary>
        public static void LogWarning(
            this AlibabacloudOptions options,
            string message)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Warning, null, message);

        /// <summary>
        /// Log a warning message.
        /// </summary>
        public static void LogWarning(
            this IDiagnosticLogger logger,
            Exception exception,
            string message)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Warning, exception, message);

        /// <summary>
        /// Log a warning message.
        /// </summary>
        public static void LogWarning(
            this AlibabacloudOptions options,
            Exception exception,
            string message)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Warning, exception, message);

        /// <summary>
        /// Log a warning message.
        /// </summary>
        public static void LogWarning<TArg>(
            this IDiagnosticLogger logger,
            string message,
            TArg arg)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Warning, null, message, arg);

        /// <summary>
        /// Log a warning message.
        /// </summary>
        public static void LogWarning<TArg>(
            this AlibabacloudOptions options,
            string message,
            TArg arg)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Warning, null, message, arg);

        /// <summary>
        /// Log a warning message.
        /// </summary>
        public static void LogWarning<TArg, TArg2>(
            this IDiagnosticLogger logger,
            string message,
            TArg arg,
            TArg2 arg2)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Warning, null, message, arg, arg2);

        /// <summary>
        /// Log a warning message.
        /// </summary>
        public static void LogWarning<TArg, TArg2>(
            this AlibabacloudOptions options,
            string message,
            TArg arg,
            TArg2 arg2)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Warning, null, message, arg, arg2);

        /// <summary>
        /// Log a warning message.
        /// </summary>
        public static void LogWarning<TArg, TArg2, TArg3>(
            this IDiagnosticLogger logger,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Warning, null, message, arg, arg2, arg3);

        /// <summary>
        /// Log a warning message.
        /// </summary>
        public static void LogWarning<TArg, TArg2, TArg3>(
            this AlibabacloudOptions options,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Warning, null, message, arg, arg2, arg3);

        /// <summary>
        /// Log a error message.
        /// </summary>
        public static void LogError(
            this IDiagnosticLogger logger,
            string message)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Error, null, message);

        /// <summary>
        /// Log an error message.
        /// </summary>
        public static void LogError<TArg>(
            this IDiagnosticLogger logger,
            string message,
            TArg arg)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Error, null, message, arg);

        /// <summary>
        /// Log an exception with an error message.
        /// </summary>
        public static void LogError(
            this IDiagnosticLogger logger,
            Exception exception,
            string message)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Error, exception, message);

        /// <summary>
        /// Log a error message.
        /// </summary>
        public static void LogError(
            this AlibabacloudOptions options,
            string message)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Error, null, message);

        /// <summary>
        /// Log a error message.
        /// </summary>
        public static void LogError(
            this AlibabacloudOptions options,
            Exception exception,
            string message)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Error, exception, message);

        /// <summary>
        /// Log a error message.
        /// </summary>
        public static void LogError<TArg>(
            this IDiagnosticLogger logger,
            Exception exception,
            string message,
            TArg arg)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Error, exception, message, arg);

        /// <summary>
        /// Log a error message.
        /// </summary>
        public static void LogError<TArg>(
            this AlibabacloudOptions options,
            Exception exception,
            string message,
            TArg arg)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Error, exception, message, arg);

        /// <summary>
        /// Log a error message.
        /// </summary>
        public static void LogError<TArg>(
            this AlibabacloudOptions options,
            string message,
            TArg arg)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Error, null, message, arg);

        /// <summary>
        /// Log a error message.
        /// </summary>
        public static void LogError<TArg, TArg2>(
            this IDiagnosticLogger logger,
            Exception exception,
            string message,
            TArg arg,
            TArg2 arg2)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Error, exception, message, arg, arg2);

        /// <summary>
        /// Log a error message.
        /// </summary>
        public static void LogError<TArg, TArg2>(
            this AlibabacloudOptions options,
            Exception exception,
            string message,
            TArg arg,
            TArg2 arg2)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Error, exception, message, arg, arg2);

        /// <summary>
        /// Log a error message.
        /// </summary>
        public static void LogError<TArg, TArg2>(
            this AlibabacloudOptions options,
            string message,
            TArg arg,
            TArg2 arg2)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Error, null, message, arg, arg2);


        /// <summary>
        /// Log an error message.
        /// </summary>
        public static void LogError<TArg, TArg2, TArg3>(
            this IDiagnosticLogger logger,
            Exception exception,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Error, exception, message, arg, arg2, arg3);

        /// <summary>
        /// Log an error message.
        /// </summary>
        public static void LogError<TArg, TArg2, TArg3>(
            this AlibabacloudOptions options,
            Exception exception,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Error, exception, message, arg, arg2, arg3);

        /// <summary>
        /// Log an error message.
        /// </summary>
        public static void LogError<TArg, TArg2, TArg3>(
            this AlibabacloudOptions options,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Error, null, message, arg, arg2, arg3);

        /// <summary>
        /// Log a error message.
        /// </summary>
        public static void LogError<TArg, TArg2, TArg3, TArg4>(
            this IDiagnosticLogger logger,
            Exception exception,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3,
            TArg4 arg4)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Error, exception, message, arg, arg2, arg3, arg4);

        /// <summary>
        /// Log a error message.
        /// </summary>
        public static void LogError<TArg, TArg2, TArg3, TArg4>(
            this AlibabacloudOptions options,
            Exception exception,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3,
            TArg4 arg4)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Error, exception, message, arg, arg2, arg3, arg4);

        /// <summary>
        /// Log a error message.
        /// </summary>
        public static void LogError<TArg, TArg2, TArg3, TArg4>(
            this AlibabacloudOptions options,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3,
            TArg4 arg4)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Error, null, message, arg, arg2, arg3, arg4);

        /// <summary>
        /// Log a error message.
        /// </summary>
        public static void LogError<TArg, TArg2, TArg3, TArg4, TArg5>(
            this AlibabacloudOptions options,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3,
            TArg4 arg4,
            TArg5 arg5)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Error, null, message, arg, arg2, arg3, arg4, arg5);

        /// <summary>
        /// Log a warning message.
        /// </summary>
        public static void LogFatal(
            this IDiagnosticLogger logger,
            string message)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Fatal, null, message);

        /// <summary>
        /// Log an exception with a warning message.
        /// </summary>
        public static void LogFatal(this IDiagnosticLogger logger,
            Exception exception,
            string message)
            => logger.LogIfEnabled(AlibabacloudLogLevel.Fatal, exception, message);

        /// <summary>
        /// Log a warning message.
        /// </summary>
        public static void LogFatal(
            this AlibabacloudOptions options,
            string message)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Fatal, null, message);

        /// <summary>
        /// Log an exception with a warning message.
        /// </summary>
        public static void LogFatal(this AlibabacloudOptions options,
            Exception exception,
            string message)
            => options?.DiagnosticLogger?.LogIfEnabled(AlibabacloudLogLevel.Fatal, exception, message);

        public static void LogIfEnabled(
            this IDiagnosticLogger logger,
            AlibabacloudLogLevel level,
            Exception? exception,
            string message)
        {
            if (logger.IsEnabled(level))
            {
                logger.Log(level, message, exception);
            }
        }

        public static void LogIfEnabled(
            this AlibabacloudOptions options,
            AlibabacloudLogLevel level,
            Exception? exception,
            string message)
        {
            var logger = options.DiagnosticLogger;
            if (logger == null)
            {
                return;
            }

            if (logger.IsEnabled(level))
            {
                logger.Log(level, message, exception);
            }
        }

        public static void LogIfEnabled<TArg>(
            this IDiagnosticLogger logger,
            AlibabacloudLogLevel level,
            Exception? exception,
            string message,
            TArg arg)
        {
            if (logger.IsEnabled(level))
            {
                logger.Log(level, message, exception, arg);
            }
        }

        public static void LogIfEnabled<TArg>(
            this AlibabacloudOptions options,
            AlibabacloudLogLevel level,
            Exception? exception,
            string message,
            TArg arg)
        {
            var logger = options.DiagnosticLogger;
            if (logger == null)
            {
                return;
            }

            if (logger.IsEnabled(level))
            {
                logger.Log(level, message, exception, arg);
            }
        }

        public static void LogIfEnabled<TArg, TArg2>(
            this IDiagnosticLogger logger,
            AlibabacloudLogLevel level,
            Exception? exception,
            string message,
            TArg arg,
            TArg2 arg2)
        {
            if (logger.IsEnabled(level))
            {
                logger.Log(level, message, exception, arg, arg2);
            }
        }

        public static void LogIfEnabled<TArg, TArg2>(
            this AlibabacloudOptions options,
            AlibabacloudLogLevel level,
            Exception? exception,
            string message,
            TArg arg,
            TArg2 arg2)
        {
            var logger = options.DiagnosticLogger;
            if (logger == null)
            {
                return;
            }

            if (logger.IsEnabled(level))
            {
                logger.Log(level, message, exception, arg, arg2);
            }
        }

        public static void LogIfEnabled<TArg, TArg2, TArg3>(
            this IDiagnosticLogger logger,
            AlibabacloudLogLevel level,
            Exception? exception,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3)
        {
            if (logger.IsEnabled(level))
            {
                logger.Log(level, message, exception, arg, arg2, arg3);
            }
        }

        public static void LogIfEnabled<TArg, TArg2, TArg3>(
            this AlibabacloudOptions options,
            AlibabacloudLogLevel level,
            Exception? exception,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3)
        {
            var logger = options.DiagnosticLogger;
            if (logger == null)
            {
                return;
            }

            if (logger.IsEnabled(level))
            {
                logger.Log(level, message, exception, arg, arg2, arg3);
            }
        }

        public static void LogIfEnabled<TArg, TArg2, TArg3, TArg4>(
            this IDiagnosticLogger logger,
            AlibabacloudLogLevel level,
            Exception? exception,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3,
            TArg4 arg4)
        {
            if (logger.IsEnabled(level))
            {
                logger.Log(level, message, exception, arg, arg2, arg3, arg4);
            }
        }

        public static void LogIfEnabled<TArg, TArg2, TArg3, TArg4, TArg5>(
            this IDiagnosticLogger logger,
            AlibabacloudLogLevel level,
            Exception? exception,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3,
            TArg4 arg4,
            TArg5 arg5)
        {
            if (logger.IsEnabled(level))
            {
                logger.Log(level, message, exception, arg, arg2, arg3, arg4, arg5);
            }
        }

        public static void LogIfEnabled<TArg, TArg2, TArg3, TArg4>(
            this AlibabacloudOptions options,
            AlibabacloudLogLevel level,
            Exception? exception,
            string message,
            TArg arg,
            TArg2 arg2,
            TArg3 arg3,
            TArg4 arg4)
        {
            var logger = options.DiagnosticLogger;
            if (logger == null)
            {
                return;
            }

            if (logger.IsEnabled(level))
            {
                logger.Log(level, message, exception, arg, arg2, arg3, arg4);
            }
        }
    }
}
