using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Commons.OpcUa;

namespace ZB.MOM.WW.OtOpcUa.Commons.Tests.OpcUa;

/// <summary>
/// Covers DeferredServiceLevelPublisher forwarding invariants (Commons-003 companion).
/// </summary>
public class DeferredServiceLevelPublisherTests
{
    [Fact]
    public void Before_SetInner_Publish_is_a_noop()
    {
        var publisher = new DeferredServiceLevelPublisher();
        // Must not throw; the NullServiceLevelPublisher absorbs it.
        publisher.Publish(200);
    }

    [Fact]
    public void After_SetInner_Publish_is_forwarded()
    {
        var spy = new SpyPublisher();
        var publisher = new DeferredServiceLevelPublisher();
        publisher.SetInner(spy);

        publisher.Publish(240);

        spy.LastPublished.ShouldBe((byte)240);
    }

    [Fact]
    public void SetInner_null_reverts_to_null_publisher()
    {
        var spy = new SpyPublisher();
        var publisher = new DeferredServiceLevelPublisher();
        publisher.SetInner(spy);
        publisher.SetInner(null); // revert

        publisher.Publish(100);

        // The spy should NOT have received the publish after revert.
        spy.LastPublished.ShouldBe((byte)0, "spy should not have been updated after revert to null");
    }

    // ---- test double ----

    private sealed class SpyPublisher : IServiceLevelPublisher
    {
        public byte LastPublished { get; private set; }
        public void Publish(byte serviceLevel) => LastPublished = serviceLevel;
    }
}
