using System.Collections.Concurrent;
using Shouldly;
using ZB.MOM.NatsNet.Server;

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

public sealed partial class ConcurrencyTests1
{
    [Fact] // T:2387
    public void NoRaceJetStreamAPIStreamListPaging_ShouldSucceed()
    {
        var names = Enumerable.Range(0, 500).Select(i => $"STREAM-{i:D4}").ToList();
        var errors = new ConcurrentQueue<Exception>();

        Parallel.For(0, 20, page =>
        {
            try
            {
                var offset = page * 10;
                var slice = names.Skip(offset).Take(10).ToArray();
                slice.Length.ShouldBe(10);
                slice[0].ShouldBe($"STREAM-{offset:D4}");
            }
            catch (Exception ex)
            {
                errors.Enqueue(ex);
            }
        });

        errors.ShouldBeEmpty();
    }

    [Fact] // T:2402
    public void NoRaceJetStreamFileStoreBufferReuse_ShouldSucceed()
    {
        WithStore((fs, _) =>
        {
            for (var i = 0; i < 2_000; i++)
                fs.StoreMsg($"reuse.{i % 8}", null, new[] { (byte)(i % 255) }, 0);

            var errors = new ConcurrentQueue<Exception>();
            Parallel.For(0, 100, i =>
            {
                try
                {
                    var subject = $"reuse.{i % 8}";
                    var msg = fs.LoadLastMsg(subject, null);
                    msg.ShouldNotBeNull();
                    msg!.Subject.ShouldBe(subject);
                }
                catch (Exception ex)
                {
                    errors.Enqueue(ex);
                }
            });

            errors.ShouldBeEmpty();
            fs.State().Msgs.ShouldBe(2_000UL);
        }, DefaultStreamConfig());
    }
}
