using NATS.Server.Configuration;
using NATS.Server.JetStream;

namespace NATS.Server.JetStream.Tests.JetStream;

public class JetStreamConfigModelParityBatch3Tests
{
    [Fact]
    public void JetStreamOptions_exposes_extended_go_config_fields()
    {
        var opts = new JetStreamOptions
        {
            SyncInterval = TimeSpan.FromSeconds(2),
            SyncAlways = true,
            CompressOk = true,
            UniqueTag = "az",
            Strict = true,
            MaxAckPending = 123,
            MemoryMaxStreamBytes = 1111,
            StoreMaxStreamBytes = 2222,
            MaxBytesRequired = true,
        };

        opts.SyncInterval.ShouldBe(TimeSpan.FromSeconds(2));
        opts.SyncAlways.ShouldBeTrue();
        opts.CompressOk.ShouldBeTrue();
        opts.UniqueTag.ShouldBe("az");
        opts.Strict.ShouldBeTrue();
        opts.MaxAckPending.ShouldBe(123);
        opts.MemoryMaxStreamBytes.ShouldBe(1111);
        opts.StoreMaxStreamBytes.ShouldBe(2222);
        opts.MaxBytesRequired.ShouldBeTrue();
    }

    [Fact]
    public void ConfigProcessor_parses_extended_jetstream_fields()
    {
        var opts = ConfigProcessor.ProcessConfig("""
            jetstream {
              store_dir: '/tmp/js'
              max_mem_store: 1024
              max_file_store: 2048
              domain: 'D'
              sync_interval: '2s'
              sync_always: true
              compress_ok: true
              unique_tag: 'az'
              strict: true
              max_ack_pending: 42
              memory_max_stream_bytes: 10000
              store_max_stream_bytes: 20000
              max_bytes_required: true
            }
            """);

        opts.JetStream.ShouldNotBeNull();
        var js = opts.JetStream!;
        js.StoreDir.ShouldBe("/tmp/js");
        js.MaxMemoryStore.ShouldBe(1024);
        js.MaxFileStore.ShouldBe(2048);
        js.Domain.ShouldBe("D");
        js.SyncInterval.ShouldBe(TimeSpan.FromSeconds(2));
        js.SyncAlways.ShouldBeTrue();
        js.CompressOk.ShouldBeTrue();
        js.UniqueTag.ShouldBe("az");
        js.Strict.ShouldBeTrue();
        js.MaxAckPending.ShouldBe(42);
        js.MemoryMaxStreamBytes.ShouldBe(10000);
        js.StoreMaxStreamBytes.ShouldBe(20000);
        js.MaxBytesRequired.ShouldBeTrue();
    }

    [Fact]
    public void JetStream_struct_models_cover_stats_limits_and_tiers()
    {
        var api = new JetStreamApiStats
        {
            Total = 10,
            Errors = 2,
            Inflight = 1,
        };

        var tier = new JetStreamTier
        {
            Name = "R3",
            Memory = 1000,
            Store = 2000,
            Streams = 3,
            Consumers = 5,
        };

        var limits = new JetStreamAccountLimits
        {
            MaxMemory = 10_000,
            MaxStore = 20_000,
            MaxStreams = 7,
            MaxConsumers = 9,
            MaxAckPending = 25,
            MemoryMaxStreamBytes = 1_000,
            StoreMaxStreamBytes = 2_000,
            MaxBytesRequired = true,
            Tiers = new Dictionary<string, JetStreamTier>
            {
                ["R3"] = tier,
            },
        };

        var stats = new JetStreamStats
        {
            Memory = 123,
            Store = 456,
            ReservedMemory = 11,
            ReservedStore = 22,
            Accounts = 2,
            HaAssets = 4,
            Api = api,
        };

        limits.Tiers["R3"].Name.ShouldBe("R3");
        limits.MaxAckPending.ShouldBe(25);
        limits.MaxBytesRequired.ShouldBeTrue();

        stats.Memory.ShouldBe(123);
        stats.Store.ShouldBe(456);
        stats.Api.Total.ShouldBe(10UL);
        stats.Api.Errors.ShouldBe(2UL);
        stats.Api.Inflight.ShouldBe(1);
    }
}
