using StackExchange.Redis;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace XYY.Core.Standard.Data.Redis
{

    public static class RedisUnit
    {

        public static async Task<long> DeleteScanKey(this IDatabase db, string pattern)
        {
            var redisResult = await db.ScriptEvaluateAsync(LuaScript.Prepare(
                            //Redis的keys模糊查询：
                            " local res = redis.call(\'KEYS\', @keypattern) " +
                            " return res "), new { @keypattern = pattern });
            if (!redisResult.IsNull)
            {
                return db.KeyDelete((RedisKey[])redisResult);
            }
            else
            {
                return 0;
            }
        }

        public static Task<long> DeleteScanKey(this IDatabase db, IBatch batch, string pattern)
        {
            var redisResult =  db.ScriptEvaluate(LuaScript.Prepare(
                            //Redis的keys模糊查询：
                            " local res = redis.call(\'KEYS\', @keypattern) " +
                            " return res "), new { @keypattern = pattern });
            if (!redisResult.IsNull)
            {
                return batch.KeyDeleteAsync((RedisKey[])redisResult);
            }
            else
            {
                return null;
            }
        }
    }


    public class RedisHelper : IDisposable
    {
        //连接字符串
        private string _connectionString;
        //实例名称
        private string _instanceName;
        //密码
        private string _password;
        //默认数据库
        private int _defaultDB;
        private ConcurrentDictionary<string, ConnectionMultiplexer> _connections;
        public RedisHelper(string connectionString, string instanceName, string password, int defaultDB = 0)
        {
            _connectionString = connectionString;
            _instanceName = instanceName;
            _password = password;
            _defaultDB = defaultDB;
            _connections = new ConcurrentDictionary<string, ConnectionMultiplexer>();
        }

        /// <summary>
        /// 获取ConnectionMultiplexer
        /// </summary>
        /// <returns></returns>
        private ConnectionMultiplexer GetConnect()
        {
            Console.WriteLine(_connectionString + ",password=" + _password);
            return _connections.GetOrAdd(_instanceName, p => ConnectionMultiplexer.Connect(_connectionString + ",password=" + _password));
        }

        /// <summary>
        /// 获取数据库
        /// </summary>
        /// <param name="configName"></param>
        /// <param name="db">默认为0：优先代码的db配置，其次config中的配置</param>
        /// <returns></returns>
        public IDatabase GetDatabase()
        {
            return GetConnect().GetDatabase(_defaultDB);
        }
        
        public IDatabase GetDatabase(int dbIndex)
        {
            return GetConnect().GetDatabase(dbIndex);
        }

        public IServer GetServer(string configName = null, int endPointsIndex = 0)
        {
            if (string.IsNullOrEmpty(configName))
                configName = _instanceName;
            var endpoint = _connections[configName].GetEndPoints()[0];
            return GetConnect().GetServer(endpoint);
        }

        public ISubscriber GetSubscriber(string configName = null)
        {
            return GetConnect().GetSubscriber();
        }

        public void Dispose()
        {
            if (_connections != null && _connections.Count > 0)
            {
                foreach (var item in _connections.Values)
                {
                    item.Close();
                }
            }
        }
    }
}
