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

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

namespace ZB.MOM.NatsNet.Server;

public sealed partial class NatsServer
{
    internal void InitOCSPResponseCache()
    {
        _mu.EnterReadLock();
        try
        {
            if (!_ocspPeerVerify)
            {
                return;
            }
        }
        finally
        {
            _mu.ExitReadLock();
        }

        var opts = GetOpts();
        opts.OcspCacheConfig ??= OcspHandler.NewOCSPResponseCacheConfig();
        var config = opts.OcspCacheConfig;

        IOcspResponseCache cache;
        var cacheType = (config.Type ?? string.Empty).Trim().ToLowerInvariant();
        switch (cacheType)
        {
            case "":
            case OcspHandler.OcspResponseCacheTypeLocal:
                config.Type = OcspHandler.OcspResponseCacheTypeLocal;
                cache = new LocalDirCache(config);
                break;

            case OcspHandler.OcspResponseCacheTypeNone:
                cache = new NoOpCache(config);
                break;

            default:
                Fatalf(OcspMessages.ErrBadCacheTypeConfig, config.Type);
                return;
        }

        _mu.EnterWriteLock();
        try
        {
            _ocsprc = cache;
        }
        finally
        {
            _mu.ExitWriteLock();
        }
    }

    internal void StartOCSPResponseCache()
    {
        IOcspResponseCache? cache;

        _mu.EnterReadLock();
        try
        {
            if (!_ocspPeerVerify)
            {
                return;
            }

            cache = _ocsprc;
        }
        finally
        {
            _mu.ExitReadLock();
        }

        if (cache == null)
        {
            return;
        }

        switch (cache)
        {
            case NoOpCache noOpCache:
                noOpCache.Start(this);
                Noticef("OCSP peer cache online [{0}]", noOpCache.Type());
                break;

            case LocalDirCache localDirCache:
                localDirCache.Start(this);
                Noticef("OCSP peer cache online [{0}]", localDirCache.Type());
                break;
        }
    }

    internal void StopOCSPResponseCache()
    {
        IOcspResponseCache? cache;

        _mu.EnterReadLock();
        try
        {
            cache = _ocsprc;
        }
        finally
        {
            _mu.ExitReadLock();
        }

        if (cache == null)
        {
            return;
        }

        switch (cache)
        {
            case NoOpCache noOpCache:
                noOpCache.Stop(this);
                break;

            case LocalDirCache localDirCache:
                localDirCache.Stop(this);
                break;
        }
    }
}
