using StackExchange.Redis;
using System;
using System.Linq;
using VCommon.Diagnostics;

namespace VCommon.Caching.Internals
{
    internal class RedisCacheAccess : CacheAccess
    {
        private readonly ConnectionMultiplexer _conn;

        internal RedisCacheAccess(string server) => _conn = ConnectionMultiplexer.Connect(server);

        // --- database ---

        private IDatabase GetDatabase(int db) => _conn.GetDatabase(db);

        public void CacheOp(int db, Action<IDatabase> action)
        {
            using (new TimeoutWarnLog(nameof(CacheAccess))) action(GetDatabase(db));
        }

        public T CacheOp<T>(int db, Func<IDatabase, T> action)
        {
            using (new TimeoutWarnLog(nameof(CacheAccess))) return action(GetDatabase(db));
        }

        public RedisKey[] SearchKeys(int db, string pattern)
        {
            return _conn.GetEndPoints()
                .SelectMany(p => _conn.GetServer(p).Keys(db, pattern, int.MaxValue))
                .ToArray();
        }
    }
}