using LY.App.Extensions.DI;
using StackExchange.Redis;
using System.Text.Json;
namespace LY.App.Common.Redis
{
    /// 
    /// redis 连接服务
    /// 
    public class RedisService
    {
        private readonly IDatabase _db;
        /// 
        /// 构造函数
        /// 
        /// 
        public RedisService(string connectionString)
        {
            var redis = ConnectionMultiplexer.Connect(connectionString);
            _db = redis.GetDatabase();
        }
        /// 
        /// 泛型存储数据到 Redis
        /// 
        public async Task SetAsync(string key, T value, TimeSpan? expiry = null)
        {
            string jsonData = JsonSerializer.Serialize(value);
            return await _db.StringSetAsync(key, jsonData, expiry);
        }
        /// 
        /// 泛型获取数据
        /// 
        public async Task GetAsync(string key)
        {
            string jsonData = await _db.StringGetAsync(key);
            return jsonData is not null ? JsonSerializer.Deserialize(jsonData) : default;
        }
        /// 
        /// 删除 Key
        /// 
        public async Task DeleteAsync(string key)
        {
            return await _db.KeyDeleteAsync(key);
        }
        /// 
        /// 检查 Key 是否存在
        /// 
        public async Task ExistsAsync(string key)
        {
            return await _db.KeyExistsAsync(key);
        }
        /// 
        /// 获取数据,如果不存在则从数据源获取并存入 Redis
        /// 
        /// 数据类型
        /// Redis Key
        /// 数据源方法
        /// 可选的过期时间
        /// 获取到的值
        public async Task GetOrSetAsync(string key, Func> factory, TimeSpan? expiry = null)
        {
            var value = await GetAsync(key);
            if (value is not null)
            {
                return value;
            }
            value = await factory();
            if (value is not null)
            {
                await SetAsync(key, value, expiry);
            }
            return value;
        }
    }
}