using Microsoft.Extensions.Logging.Abstractions;

namespace adas_core.Logging;

/// <summary>
/// Provides a static interface for logging functionality across the application.
/// </summary>
/// <remarks>
/// As a static class, it cannot be instantiated or inherited and is intended to expose
/// logging operations as shared members.
/// </remarks>
public static class LogProvider
{
    private static ILoggerFactory? _loggerFactory;

    /// <summary>
    ///     Sets the current log provider based on logger factory.
    /// </summary>
    /// <param name="loggerFactory">The logger factory.</param>
    public static void SetLogProvider(ILoggerFactory loggerFactory)
    {
        _loggerFactory = loggerFactory;
    }

    /// <summary>
    /// Creates an <see cref="ILogger"/> for the specified category. If a logger factory has been configured, it is used to create the logger; otherwise, a <see cref="NullLogger"/> is returned as a fallback.
    /// </summary>
    /// <param name="category">The category name for the logger to create.</param>
    /// <returns>An <see cref="ILogger"/> instance for the specified category, or a <see cref="NullLogger"/> when no logger factory is available.</returns>
    public static ILogger CreateLogger(string category)
    {
        if (_loggerFactory != null) return _loggerFactory.CreateLogger(category);

        return NullLogger.Instance;
    }

    /// <summary>
    /// Creates an <see cref="ILogger{T}"/> instance using the configured logger factory, or returns a <see cref="NullLogger{T}"/> instance when no factory has been set.
    /// </summary>
    /// <returns>An <see cref="ILogger{T}"/> produced by the underlying <see cref="ILoggerFactory"/> if available; otherwise, a shared <see cref="NullLogger{T}"/> instance used as a no-op fallback.</returns>
    public static ILogger<T> CreateLogger<T>()
    {
        if (_loggerFactory != null) return _loggerFactory.CreateLogger<T>();

        return NullLogger<T>.Instance;
    }

#if DIAGNOSTICS_SOURCE
        /// <summary>
        /// Provides static utility members for caching values within the assembly.
        /// </summary>
        internal static class Cached
        {
            internal static readonly System.Lazy<System.Diagnostics.DiagnosticListener> Default =
                new(() => new System.Diagnostics.DiagnosticListener(DiagnosticHeaders.DefaultListenerName));
        }
#endif
}