// Copyright 2012-2026 The NATS Authors
// Licensed under the Apache License, Version 2.0

using Shouldly;
using ZB.MOM.NatsNet.Server.Auth.Ocsp;

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

public sealed class OcspResponseCacheTests
{
    [Fact]
    public void LocalDirCache_GetPutRemove_ShouldPersistToDisk()
    {
        var dir = Path.Combine(Path.GetTempPath(), $"ocsp-{Guid.NewGuid():N}");
        Directory.CreateDirectory(dir);
        try
        {
            var cache = new LocalDirCache(dir);
            cache.Get("abc").ShouldBeNull();

            cache.Put("abc", [1, 2, 3]);
            cache.Get("abc").ShouldBe([1, 2, 3]);

            cache.Remove("abc");
            cache.Get("abc").ShouldBeNull();
        }
        finally
        {
            Directory.Delete(dir, recursive: true);
        }
    }

    [Fact]
    public void NoOpCache_LifecycleAndStats_ShouldNoOpSafely()
    {
        var noOp = new NoOpCache();
        noOp.Online().ShouldBeFalse();
        noOp.Type().ShouldBe("none");
        noOp.Config().ShouldNotBeNull();
        noOp.Stats().ShouldBeNull();

        noOp.Start();
        noOp.Online().ShouldBeTrue();
        noOp.Stats().ShouldNotBeNull();

        noOp.Put("k", [5]);
        noOp.Get("k").ShouldBeNull();
        noOp.Remove("k"); // alias to Delete
        noOp.Delete("k");

        noOp.Stop();
        noOp.Online().ShouldBeFalse();
    }

    [Fact]
    public void OcspMonitor_StartAndStop_ShouldLoadStaple()
    {
        var dir = Path.Combine(Path.GetTempPath(), $"ocsp-monitor-{Guid.NewGuid():N}");
        Directory.CreateDirectory(dir);
        try
        {
            var stapleFile = Path.Combine(dir, "staple.bin");
            File.WriteAllBytes(stapleFile, [9, 9]);

            var monitor = new OcspMonitor
            {
                OcspStapleFile = stapleFile,
                CheckInterval = TimeSpan.FromMilliseconds(10),
            };

            monitor.Start();
            Thread.Sleep(30);
            monitor.GetStaple().ShouldBe([9, 9]);
            monitor.Stop();
        }
        finally
        {
            Directory.Delete(dir, recursive: true);
        }
    }
}
