using Shouldly;

namespace ZB.MOM.NatsNet.Server.Tests.JetStream;

public sealed class RaftNodeTests
{
    [Fact]
    public void NRGMultipleStopsDontPanic_ShouldSucceed()
    {
        var raft = InitSingleMemRaftNode();

        Should.NotThrow(() =>
        {
            for (var i = 0; i < 10; i++)
                raft.Stop();
        });

        raft.State().ShouldBe(RaftState.Closed);
    }

    [Fact]
    public void NRGKeepRunningOnServerShutdown_ShouldSucceed()
    {
        var raft = InitSingleMemRaftNode();

        raft.Run();
        raft.State().ShouldBe(RaftState.Follower);

        raft.Stop();
        raft.WaitForStop();

        raft.State().ShouldBe(RaftState.Closed);
    }

    [Fact]
    public void NRGInitSingleMemRaftNodeDefaults_ShouldSucceed()
    {
        var raft = InitSingleMemRaftNode();

        raft.ID().ShouldBe("esFhDys3");
        raft.Peers().Count.ShouldBe(1);
        raft.Peers()[0].Id.ShouldBe("esFhDys3");
        raft.ClusterSize().ShouldBe(1);
        raft.Quorum().ShouldBeTrue();
    }

    private static Raft InitSingleMemRaftNode()
    {
        return new Raft
        {
            Id = "esFhDys3",
            GroupName = "RG",
            Csz = 1,
            Qn = 1,
            Peers_ = new Dictionary<string, Lps>
            {
                ["esFhDys3"] = new() { Kp = true, Ts = DateTime.UtcNow },
            },
            Quit = System.Threading.Channels.Channel.CreateUnbounded<bool>(),
        };
    }
}
