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

using StackExchange.Redis;

namespace RedisStuy
{
    /// <summary>
    /// 链表学习
    /// http://www.redis.cn
    /// http://www.redis.net.cn/order/
    /// </summary>
    public class RedisListStudy
    {
        #region 初始化
        private IDatabase redisDatabase;

        public RedisListStudy()
        {
            redisDatabase = RedisHelper.GetRedisDatabase();
        }
        #endregion

        /// <summary>
        /// 在列表的元素前(左)插入元素
        /// </summary>
        /// <returns>
        /// 命令执行成功,返回插入操作完成之后,列表的长度
        /// 没有找到指定元素 ,返回 -1
        /// key 不存在或为空列表,返回 0 
        /// </returns>
        public long ListLeftPush(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.ListLeftPush(key, value, when, flags);
        }

        /// <summary>
        /// 在列表的元素前(左)插入一组元素
        /// </summary>
        /// <returns>
        /// 命令执行成功,返回插入操作完成之后,列表的长度
        /// 没有找到指定元素 ,返回 -1
        /// key 不存在或为空列表,返回 0 
        /// </returns>
        public long ListLeftPushs(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.ListLeftPush(key, values, flags);
        }


        /// <summary>
        /// 在列表的元素后(右)插入元素
        /// </summary>
        /// <returns>
        /// 命令执行成功,返回插入操作完成之后,列表的长度
        /// 没有找到指定元素 ,返回 -1
        /// key 不存在或为空列表,返回 0 
        /// </returns>
        public long ListRightPush(RedisKey key, RedisValue value, When when = When.Always, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.ListRightPush(key, value, when, flags);
        }

        /// <summary>
        /// 在列表的元素后面(右侧)插入一组元素
        /// </summary>
        /// <returns>
        /// 命令执行成功,返回插入操作完成之后,列表的长度
        /// 没有找到指定元素 ,返回 -1
        /// key 不存在或为空列表,返回 0 
        /// </returns>
        public long ListRightPush(RedisKey key, RedisValue[] values, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.ListRightPush(key, values, flags);
        }

        /// <summary>
        /// 在列表中指定元素后插入元素
        /// 指定key不存在,不执行任何操作
        /// </summary>
        /// <returns>
        /// 插入后,列表长度
        /// 未找到指定key值时,返回 -1
        /// </returns>
        public long ListInsertAfter(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None)
        {

            return redisDatabase.ListInsertAfter(key, pivot, value, flags);
        }

        /// <summary>
        /// 在列表中指定元素前插入元素
        /// 指定key不存在,不执行任何操作
        /// </summary>
        /// <returns>
        /// 插入后,列表长度
        /// 未找到指定key值时,返回 -1
        /// </returns>
        public long ListInsertBefore(RedisKey key, RedisValue pivot, RedisValue value, CommandFlags flags = CommandFlags.None)
        {

            return redisDatabase.ListInsertBefore(key, pivot, value, flags);
        }

        /// <summary>
        /// 移出并获取列表的第一个元素
        /// </summary>
        /// <returns>
        /// 列表的第一个元素
        /// 当列表 key 不存在时,返回 nil
        /// </returns>
        public RedisValue ListLeftPop(RedisKey key, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.ListLeftPop(key, flags);
        }

        /// <summary>
        /// 移除并返回列表的最后一个元素
        /// </summary>
        /// <returns>
        /// 列表的最后一个元素
        /// 当列表不存在时,返回 nil 
        /// </returns>
        public RedisValue ListRightPop(RedisKey key, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.ListRightPop(key, flags);
        }

        /// <summary>
        /// 获取列表长度
        /// </summary>
        /// <returns>
        /// 列表的长度
        /// 不存在时返回0
        /// </returns>
        public long ListLength(RedisKey key, CommandFlags flags = CommandFlags.None)
        {
          return  redisDatabase.ListLength(key, flags);
        }

        /// <summary>
        /// 获取列表指定范围内的元素
        ///  0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推。 
        ///  负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推
        /// </summary>
        /// <returns>
        ///  指定区间内元素列表
        /// </returns>
        public RedisValue[] ListRange(RedisKey key, long start = 0, long stop = -1, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.ListRange(key, start, stop, flags);
        }

        /// <summary>
        /// 移除列表中与值相等的元素
        /// count > 0:从 头到尾 的移除值相等的元素
        /// count < 0:从 尾到头 的移除值相等的元素
        /// count =0:移除所有与值相等的元素
        /// </summary>
        /// <returns>
        /// </returns>
        public long ListRemove(RedisKey key, RedisValue value, long count = 0, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.ListRemove(key, value, count, flags);
        }

        /// <summary>
        /// 通过索引获取列表中的元素
        /// </summary>
        public RedisValue ListGetByIndex(RedisKey key, long index, CommandFlags flags=CommandFlags.None)
        {
            return redisDatabase.ListGetByIndex(key, index, flags);
        }

        /// <summary>
        /// 原子的,返回并移除源列表的最后一个元素(尾部),并将元素存储在目标列表的第一个元素(头)中
        /// (原子的,把一个列表尾部的元素移动到另一个列表的头部)
        /// </summary>
        public RedisValue ListRightPopLeftPush(RedisKey source, RedisKey destination, CommandFlags flags = CommandFlags.None)
        {
            return redisDatabase.ListRightPopLeftPush(source, destination, flags);
        }

        /// <summary>
        /// 设置列表中指定索引的元素的值
        /// </summary>
        public void ListSetByIndex(RedisKey key, long index, RedisValue value, CommandFlags flags = CommandFlags.None)
        {
             redisDatabase.ListSetByIndex(key, index, value, flags);
        }

        /// <summary>
        /// 修剪(trim)列表
        /// 让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
        /// </summary>
        public void ListTrim(RedisKey key, long start, long stop, CommandFlags flags = CommandFlags.None)
        {
            redisDatabase.ListTrim(key, start, stop, flags);
        }
    }
}