using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using RedisStudyModel;

using StackExchange.Redis;

namespace RedisStuy
{
    /// <summary>
    /// Redis Hash 学习
    /// </summary>
    /// <remarks>
    /// http://www.redis.net.cn
    /// </remarks>
    public class RedisHashStudy
    {
        #region 初始化
        private IDatabase redisDatabase = RedisHelper.GetRedisDatabase();
        #endregion

        /// <summary>
        /// 整数减少hash中,指定列的值
        /// key不存在,则创建一个持有哈希的新密钥。
        /// hashField字段不存在或持有不能被解释为整数的字符串,则在执行前将该值设置为0
        /// </summary>
        public long HashDecrement(RedisKey key, RedisValue hashField, long value=1, CommandFlags flags=CommandFlags.None)
        {
            return redisDatabase.HashDecrement(key, hashField, value, flags);
        }

        /// <summary>
        /// 浮点数减少hash中,指定列的值
        /// key不存在,则创建一个持有哈希的新密钥。
        /// hashField字段不存在或持有不能被解释为整数的字符串,则在执行前将该值设置为0
        /// </summary>
        public double HashDecrement(RedisKey key, RedisValue hashField, double value = 1, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.HashDecrement(key, hashField, value, flags);
        }

        /// <summary>
        /// 删除哈希表中指定字段,不存在的字段将被忽略
        /// </summary>
        public bool HashDelete(RedisKey key, RedisValue hashField, CommandFlags flags=CommandFlags.None)
        {
            return redisDatabase.HashDelete(key, hashField, flags);
        }

        /// <summary>
        /// 删除哈希表中多个指定字段,不存在的字段将被忽略
        /// </summary>
        public long HashDelete(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.HashDelete(key, hashFields, flags);
        }

        /// <summary>
        /// 哈希表中指定字段是否存在
        /// </summary>
        public bool HashExists(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.HashExists(key, hashField, flags);
        }

        /// <summary>
        /// 获取哈希表中指定字段的值
        /// </summary>
        public RedisValue HashGet(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.HashGet(key, hashField, flags);
        }

        /// <summary>
        /// 获取哈希表中一组字段的一组值
        /// </summary>
        public RedisValue[] HashGet(RedisKey key, RedisValue[] hashFields, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.HashGet(key, hashFields, flags);
        }

        /// <summary>
        /// 获取哈希表所有字段
        /// </summary>
        public HashEntry[] HashGetAll(RedisKey key, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.HashGetAll(key, flags);
        }

        /// <summary>
        /// 整数增加hash中,指定列的值
        /// key不存在,则创建一个持有哈希的新密钥。
        /// hashField字段不存在或持有不能被解释为整数的字符串,则在执行前将该值设置为0
        /// </summary>
        public long HashIncrement(RedisKey key, RedisValue hashField, long value = 1, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.HashIncrement(key, hashField, value, flags);
        }

        /// <summary>
        /// 浮点数增加hash中,指定列的值
        /// key不存在,则创建一个持有哈希的新密钥。
        /// hashField字段不存在或持有不能被解释为整数的字符串,则在执行前将该值设置为0
        /// </summary>
        public double HashIncrement(RedisKey key, RedisValue hashField, double value = 1, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.HashIncrement(key, hashField, value, flags);
        }

        /// <summary>
        /// 获取哈希表中所有的字段
        /// </summary>
        public RedisValue[] HashKeys(RedisKey key, CommandFlags flags=CommandFlags.None)
        {
            return redisDatabase.HashKeys(key, flags);
        }

        /// <summary>
        /// 获取哈希表中字段的数量
        /// </summary>
        public long HashLength(RedisKey key, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.HashLength(key, flags);
        }

        /// <summary>
        /// 获取哈希表中所有字段的值
        /// </summary>
        public RedisValue[] HashValues(RedisKey key, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.HashValues(key, flags);
        }

        /// <summary>
        /// 为哈希表中的字段赋值
        /// 如果字段是哈希表中的一个新建字段,并且值设置成功,返回 true
        /// 如果哈希表中域字段已经存在且旧值已被新值覆盖,返回 false
        /// </summary>
        public bool HashSet(RedisKey key, RedisValue hashField, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.HashSet(key, hashField, value, when, flags);
        }

        /// <summary>
        /// 同时将多个 field-value (字段-值)对设置到哈希表中。
        /// 此命令会覆盖哈希表中已存在的字段。
        /// 如果哈希表不存在,会创建一个空哈希表,并执行 HMSET 操作。
        /// </summary>
        public bool HashSet(RedisKey key, HashEntry[] hashFields, CommandFlags flags = CommandFlags.None)
        {
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException("key", "参数 key, 不能为null值或空串");
            }

            if (hashFields == null)
            {
                throw new ArgumentNullException("hashFields", "参数 hashFields, 不能为null值");
            }

            if (hashFields.Length <= 0)
            {
                throw new ArgumentNullException("hashFields", "参数hashFields.Length ");
            }

            redisDatabase.HashSet(key, hashFields, flags);
            bool result = false;
            try
            {

                result = true;
            }
            catch (ArgumentNullException argumentNullException)
            {
                throw argumentNullException;
            }
            catch (Exception baseException)
            {
                throw baseException;
            }

            return result;
        }

        /// <summary>
        /// HSCAN命令用于对哈希进行增量迭代
        /// </summary>
        public IEnumerable<HashEntry> HashScan(RedisKey key, RedisValue pattern, int pageSize, CommandFlags flags)
        {
            return redisDatabase.HashScan(key, pattern, pageSize, flags);
        }

        /// <summary>
        /// HSCAN命令用于对哈希进行增量迭代;
        /// 注意:通过光标恢复迭代,将原始枚举或枚举器转换为ISCANIN光标。
        /// </summary>
        public IEnumerable<HashEntry> HashScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = 10, long cursor = 0, int pageOffset = 0, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.HashScan(key, pattern, pageSize,cursor,pageOffset, flags);
        }
    }
}