using Serilog;
using Serilog.Events;

namespace ScadaLink.Host;

/// <summary>
/// Builds the Serilog <see cref="LoggerConfiguration"/> for the Host process.
///
/// REQ-HOST-8 / Host-011: the configured minimum level comes from
/// <c>ScadaLink:Logging:MinimumLevel</c> (bound to <see cref="LoggingOptions"/>) so an
/// operator editing that key changes the effective log level.
///
/// REQ-HOST-8 / Host-014: the console and file sinks are read from the standard
/// <c>Serilog</c> configuration section via <c>ReadFrom.Configuration</c> — the sink
/// set, console output template, file path and rolling interval are all
/// configuration-driven (defined in <c>appsettings.json</c>), not hard-coded. The
/// explicit <c>MinimumLevel.Is</c> below pins the floor from <see cref="LoggingOptions"/>.
/// </summary>
public static class LoggerConfigurationFactory
{
    public static LoggerConfiguration Build(
        IConfiguration configuration,
        string nodeRole,
        string siteId,
        string nodeHostname)
    {
        var loggingOptions = new LoggingOptions();
        configuration.GetSection("ScadaLink:Logging").Bind(loggingOptions);

        var minimumLevel = ParseLevel(loggingOptions.MinimumLevel);

        return new LoggerConfiguration()
            .ReadFrom.Configuration(configuration)
            .MinimumLevel.Is(minimumLevel)
            .Enrich.WithProperty("SiteId", siteId)
            .Enrich.WithProperty("NodeHostname", nodeHostname)
            .Enrich.WithProperty("NodeRole", nodeRole);
    }

    /// <summary>
    /// Parses a Serilog <see cref="LogEventLevel"/> name, falling back to
    /// <see cref="LogEventLevel.Information"/> for null/blank/unrecognised values.
    /// </summary>
    private static LogEventLevel ParseLevel(string? level)
    {
        return Enum.TryParse<LogEventLevel>(level, ignoreCase: true, out var parsed)
            ? parsed
            : LogEventLevel.Information;
    }
}
