using ZB.MOM.WW.ScadaBridge.Commons.Types;

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

/// <summary>
/// Bundle E (M6-T6) regression coverage. The site-side audit-log SQLite writer
/// exposes a backlog snapshot (<c>SiteAuditBacklogSnapshot</c>) via the
/// <c>ISiteAuditQueue.GetBacklogStatsAsync</c> surface. A periodic
/// <c>SiteAuditBacklogReporter</c> hosted service polls that snapshot and
/// pushes it into the collector via <see cref="ISiteHealthCollector.UpdateSiteAuditBacklog"/>
/// so the next <see cref="ISiteHealthCollector.CollectReport"/> includes it in
/// the report payload as <c>SiteAuditBacklog</c>. Unlike the
/// SiteAuditWriteFailures / AuditRedactionFailure interval counters, the
/// backlog snapshot is not reset on collect — the field carries forward
/// whatever the most recent refresh pushed in.
/// </summary>
public class SiteAuditBacklogMetricTests
{
    private readonly SiteHealthCollector _collector = new();

    [Fact]
    public void Update_Then_CollectReport_IncludesBacklog()
    {
        var snapshot = new SiteAuditBacklogSnapshot(
            PendingCount: 42,
            OldestPendingUtc: new DateTime(2026, 5, 20, 10, 0, 0, DateTimeKind.Utc),
            OnDiskBytes: 1234567);

        _collector.UpdateSiteAuditBacklog(snapshot);

        var report = _collector.CollectReport("site-1");

        Assert.Equal(snapshot, report.SiteAuditBacklog);
    }

    [Fact]
    public void Report_Payload_Includes_SiteAuditBacklog_AsNullByDefault()
    {
        // No refresh has been pushed yet — the report carries null so the
        // central UI can distinguish "no data yet" from "queue empty".
        var report = _collector.CollectReport("site-1");

        Assert.Null(report.SiteAuditBacklog);
    }

    [Fact]
    public void CollectReport_DoesNotReset_SiteAuditBacklog()
    {
        // Backlog snapshot is a point-in-time reading, not a per-interval
        // counter — successive CollectReport calls before the next
        // SiteAuditBacklogReporter tick MUST keep returning the same snapshot
        // so a slow refresh cadence doesn't blank the central dashboard.
        var snapshot = new SiteAuditBacklogSnapshot(
            PendingCount: 7,
            OldestPendingUtc: null,
            OnDiskBytes: 8192);

        _collector.UpdateSiteAuditBacklog(snapshot);

        var first = _collector.CollectReport("site-1");
        var second = _collector.CollectReport("site-1");

        Assert.Equal(snapshot, first.SiteAuditBacklog);
        Assert.Equal(snapshot, second.SiteAuditBacklog);
    }

    [Fact]
    public void Update_With_Null_Throws_ArgumentNullException()
    {
        Assert.Throws<ArgumentNullException>(
            () => _collector.UpdateSiteAuditBacklog(null!));
    }
}
