using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
using ZiggyCreatures.Caching.Fusion;
using ZiggyCreatures.Caching.Fusion.Backplane.StackExchangeRedis;

namespace Tiku.Infrastructure.Caching;

public static class BusinessCachingServiceCollectionExtensions
{
    public const string CacheName = "TikuBusiness";

    public static IServiceCollection AddBusinessCaching(
        this IServiceCollection services,
        string environmentName,
        bool useRedis)
    {
        ArgumentException.ThrowIfNullOrWhiteSpace(environmentName);

        var normalizedEnvironment = Normalize(environmentName);
        var prefix = $"tiku:{normalizedEnvironment}:business:v2";
        var builder = services.AddFusionCache(CacheName)
            .WithOptions(options =>
            {
                options.CacheKeyPrefix = $"{prefix}:";
                options.BackplaneChannelPrefix = prefix;
                options.DistributedCacheCircuitBreakerDuration = TimeSpan.FromSeconds(2);
            })
            .WithDefaultEntryOptions(options =>
            {
                options.IsFailSafeEnabled = false;
                options.AllowBackgroundDistributedCacheOperations = false;
                options.AllowBackgroundBackplaneOperations = false;
            })
            .WithSystemTextJsonSerializer()
            .AsKeyedServiceByCacheName();

        if (useRedis)
            builder
                .WithRegisteredDistributedCache()
                .WithBackplane(serviceProvider => new RedisBackplane(
                    new RedisBackplaneOptions
                    {
                        ConnectionMultiplexerFactory = () => Task.FromResult(
                            serviceProvider.GetRequiredService<IConnectionMultiplexer>())
                    },
                    serviceProvider.GetService<ILogger<RedisBackplane>>()));

        return services;
    }

    private static string Normalize(string value)
    {
        return value.Trim().ToLowerInvariant().Replace(' ', '-');
    }
}
