// ReSharper disable once CheckNamespace
namespace Xunit.Abstractions
{
    using System;
    using System.Runtime.CompilerServices;
    using Divergic.Logging.Xunit;
    using Microsoft.Extensions.Logging;
    /// 
    ///     The  class provides extension methods for the
    ///     .
    /// 
    public static class TestOutputHelperExtensions
    {
        /// 
        ///     Builds a logger from the specified test output helper.
        /// 
        /// The test output helper.
        /// 
        ///     The member to create the logger for. This is automatically populated using 
        ///     .
        /// 
        /// The logger.
        /// The  is null.
        public static ICacheLogger BuildLogger(
            this ITestOutputHelper output,
            [CallerMemberName] string memberName = "")
        {
            return BuildLogger(output, null, memberName);
        }
        /// 
        ///     Builds a logger from the specified test output helper.
        /// 
        /// The test output helper.
        /// The minimum log level to output.
        /// 
        ///     The member to create the logger for. This is automatically populated using 
        ///     .
        /// 
        /// The logger.
        /// The  is null.
        public static ICacheLogger BuildLogger(
            this ITestOutputHelper output,
            LogLevel logLevel,
            [CallerMemberName] string memberName = "")
        {
            var config = new LoggingConfig
            {
                LogLevel = logLevel
            };
            return BuildLogger(output, config, memberName);
        }
        /// 
        ///     Builds a logger from the specified test output helper.
        /// 
        /// The test output helper.
        /// Optional logging configuration.
        /// 
        ///     The member to create the logger for. This is automatically populated using 
        ///     .
        /// 
        /// The logger.
        /// The  is null.
        public static ICacheLogger BuildLogger(
            this ITestOutputHelper output,
            LoggingConfig? config,
            [CallerMemberName] string memberName = "")
        {
            output = output ?? throw new ArgumentNullException(nameof(output));
            // Do not use the using keyword here because the factory will be disposed before the cache logger is finished with it
            var factory = LogFactory.Create(output, config);
            var logger = factory.CreateLogger(memberName);
            return logger.WithCache(factory);
        }
        /// 
        ///     Builds a logger from the specified test output helper for the specified type.
        /// 
        /// The type to create the logger for.
        /// The test output helper.
        /// The logger.
        /// The  is null.
        public static ICacheLogger BuildLoggerFor(this ITestOutputHelper output)
        {
            return BuildLoggerFor(output, null);
        }
        /// 
        ///     Builds a logger from the specified test output helper for the specified type.
        /// 
        /// The type to create the logger for.
        /// The test output helper.
        /// The minimum log level to output.
        /// The logger.
        /// The  is null.
        public static ICacheLogger BuildLoggerFor(this ITestOutputHelper output, LogLevel logLevel)
        {
            var config = new LoggingConfig
            {
                LogLevel = logLevel
            };
            return BuildLoggerFor(output, config);
        }
        /// 
        ///     Builds a logger from the specified test output helper for the specified type.
        /// 
        /// The type to create the logger for.
        /// The test output helper.
        /// Optional logging configuration.
        /// The logger.
        /// The  is null.
        public static ICacheLogger BuildLoggerFor(this ITestOutputHelper output, LoggingConfig? config)
        {
            output = output ?? throw new ArgumentNullException(nameof(output));
            // Do not use the using keyword here because the factory will be disposed before the cache logger is finished with it
            var factory = LogFactory.Create(output, config);
            var logger = factory.CreateLogger();
            return logger.WithCache(factory);
        }
        
        /// 
        ///     Builds a logger factory from the specified test output helper.
        /// 
        /// The test output helper.
        /// The logger factory.
        /// The  is null.
        public static ILoggerFactory BuildLoggerFactory(
            this ITestOutputHelper output)
        {
            return BuildLoggerFactory(output, null);
        }
        /// 
        ///     Builds a logger factory from the specified test output helper.
        /// 
        /// The test output helper.
        /// The minimum log level to output.
        /// The logger factory.
        /// The  is null.
        public static ILoggerFactory BuildLoggerFactory(
            this ITestOutputHelper output,
            LogLevel logLevel)
        {
            var config = new LoggingConfig
            {
                LogLevel = logLevel
            };
            return BuildLoggerFactory(output, config);
        }
        /// 
        ///     Builds a logger factory from the specified test output helper.
        /// 
        /// The test output helper.
        /// Optional logging configuration.
        /// The logger factory.
        /// The  is null.
        public static ILoggerFactory BuildLoggerFactory(
            this ITestOutputHelper output,
            LoggingConfig? config)
        {
            output = output ?? throw new ArgumentNullException(nameof(output));
            // Do not use the using keyword here because the factory will be disposed before the cache logger is finished with it
            var factory = LogFactory.Create(output, config);
            return factory;
        }
    }
}