using System.Diagnostics.Metrics;

namespace Tiku.Infrastructure.Security;

public static class AuthorizationCacheTelemetry
{
    public const string MeterName = "Tiku.Security.AuthorizationCache";
    private static readonly Meter Meter = new(MeterName, "1.0.0");
    private static readonly Counter<long> ReadCounter = Meter.CreateCounter<long>("tiku.authorization_cache.reads");

    private static readonly Counter<long> FallbackCounter =
        Meter.CreateCounter<long>("tiku.authorization_cache.postgres_fallbacks");

    private static readonly Counter<long> InvalidationCounter =
        Meter.CreateCounter<long>("tiku.authorization_cache.invalidations");

    private static readonly Counter<long> VersionMismatchCounter =
        Meter.CreateCounter<long>("tiku.authorization_cache.version_mismatches");

    private static readonly Counter<long> ShadowMismatchCounter =
        Meter.CreateCounter<long>("tiku.authorization_cache.shadow_mismatches");

    private static readonly Histogram<double> RedisDuration =
        Meter.CreateHistogram<double>("tiku.authorization_cache.redis.duration", "ms");

    public static void Read(string source, bool hit)
    {
        ReadCounter.Add(1,
            new KeyValuePair<string, object?>("source", source),
            new KeyValuePair<string, object?>("hit", hit));
    }

    public static void PostgresFallback()
    {
        FallbackCounter.Add(1);
    }

    public static void Invalidated(string target, bool succeeded)
    {
        InvalidationCounter.Add(1,
            new KeyValuePair<string, object?>("target", target),
            new KeyValuePair<string, object?>("succeeded", succeeded));
    }

    public static void VersionMismatch()
    {
        VersionMismatchCounter.Add(1);
    }

    public static void ShadowCompared(bool match)
    {
        if (!match) ShadowMismatchCounter.Add(1);
    }

    public static void RecordRedisDuration(double milliseconds)
    {
        RedisDuration.Record(milliseconds);
    }
}