using Serilog;
using Serilog.Events;

namespace ZB.MOM.WW.ScadaBridge.Host.Tests;

/// <summary>
/// WP-14: Tests for Serilog structured logging with enriched properties.
/// </summary>
public class SerilogTests
{
    [Fact]
    public void SerilogLogger_EnrichesWithNodeProperties()
    {
        var sink = new InMemorySink();

        var logger = new LoggerConfiguration()
            .Enrich.WithProperty("SiteId", "TestSite")
            .Enrich.WithProperty("NodeHostname", "test-node1")
            .Enrich.WithProperty("NodeRole", "Site")
            .WriteTo.Sink(sink)
            .CreateLogger();

        logger.Information("Test log message");

        Assert.Single(sink.LogEvents);
        var logEvent = sink.LogEvents[0];

        Assert.True(logEvent.Properties.ContainsKey("SiteId"));
        Assert.Equal("\"TestSite\"", logEvent.Properties["SiteId"].ToString());

        Assert.True(logEvent.Properties.ContainsKey("NodeHostname"));
        Assert.Equal("\"test-node1\"", logEvent.Properties["NodeHostname"].ToString());

        Assert.True(logEvent.Properties.ContainsKey("NodeRole"));
        Assert.Equal("\"Site\"", logEvent.Properties["NodeRole"].ToString());
    }

    [Fact]
    public void SerilogLogger_CentralRole_EnrichesSiteIdAsCentral()
    {
        var sink = new InMemorySink();

        var logger = new LoggerConfiguration()
            .Enrich.WithProperty("SiteId", "central")
            .Enrich.WithProperty("NodeHostname", "central-node1")
            .Enrich.WithProperty("NodeRole", "Central")
            .WriteTo.Sink(sink)
            .CreateLogger();

        logger.Warning("Central warning");

        Assert.Single(sink.LogEvents);
        var logEvent = sink.LogEvents[0];

        Assert.Equal(LogEventLevel.Warning, logEvent.Level);
        Assert.Equal("\"central\"", logEvent.Properties["SiteId"].ToString());
        Assert.Equal("\"Central\"", logEvent.Properties["NodeRole"].ToString());
    }
}

/// <summary>
/// Simple in-memory Serilog sink for testing.
/// </summary>
public class InMemorySink : Serilog.Core.ILogEventSink
{
    public List<LogEvent> LogEvents { get; } = new();

    public void Emit(LogEvent logEvent)
    {
        LogEvents.Add(logEvent);
    }
}
