package com.zcxk.core.utils;

import org.springframework.data.redis.core.ZSetOperations.TypedTuple;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 缓存客户端接口类
 */
/**
 * @author Andy
 * @date 2021-07-22 11:03
 */
public interface CacheClient {

    /**
    * 设置对象
    * @author Andy
    * @date 11:36 2021/8/3
    * @param realKey:
    * @param t:
    * @param timeout:
    * @return boolean
    **/
    <T> boolean setWithTtl(String realKey, T t, Long timeout);

    /**
     * 获取对象
    * @author Andy
    * @date 11:17 2021/8/3
    * @param realKey
    * @return T
    **/
    <T> T get(String realKey);

    /**
     * 删除缓存key
     * @param realKey key
     */ 
    void delete(String... realKey);


    /**
     * 单独设置key的过期时间，只允许用于刷新缓存时间使用
     * @param key
     * @param timeout
     */
    void setWithTtlByKey(String key, Long timeout);

    /**
     * 指定前缀key,保存map数据
    * @author Andy
    * @date 11:31 2021/8/3
    * @param key:
    * @param map:
    * @param timeout:
    * @return void
    **/
    void hmSetWithTtl(String key, Map<? extends Object, ? extends Object> map,
                      Long timeout);

    /**
     * 指定前缀realKey,map数据的hashKey的value值
    * @author Andy
    * @date 11:31 2021/8/3
    * @param realKey:
    * @param hashKey:
    * @param value:
    * @param timeout:
    * @return void
    **/
    void hSetWithTtl(String realKey, Object hashKey, Object value, Long timeout);

    /**
     * 指定前缀key,map数据的hashKey指定增量值increment
    * @author Andy
    * @date 11:31 2021/8/3
    * @param key:
    * @param hashKey:
    * @param increment:
    * @param timeout:
    * @return void
    **/
    void hincrbyWithTtl(String key, Object hashKey, Long increment, Long timeout);

    /**
     * 获取map保存entries的key的value值
    * @author Andy
    * @date 11:31 2021/8/3
    * @param key:
    * @param hashKey:
    * @return T
    **/
    <T> T hGet(String key, Object hashKey);

    /**
     * hMultiGet
    * @author Andy
    * @date 11:31 2021/8/3
    * @param key:
    * @param hashKeys:
    * @return java.util.List<T>
    **/
    <T> List<T> hMultiGet(String key, List<Object> hashKeys);

    /**
     * 获取key数据
    * @author Andy
    * @date 11:32 2021/8/3
    * @param key:
    * @return java.util.Map<java.lang.Object,java.lang.Object>
    **/
    Map<Object, Object> hGetAll(String key);

    /**
     * 删除hash表中的值
    * @author Andy
    * @date 11:32 2021/8/3
    * @param key:
    * @param item:
    * @return void
    **/
    void hdel(String key, Object... item);

    /**
     * 是否存在key
    * @author Andy
    * @date 11:32 2021/8/3
    * @param key:
    * @return boolean
    **/
    boolean isExistKey(String key);

    /**
     * 为键 key 储存的数字值加上增量 increment
    * @author Andy
    * @date 11:32 2021/8/3
    * @param key:
    * @param delta:
    * @param timeout:
    * @return java.lang.Long
    **/
    Long incrementWithTtl(String key, long delta, Long timeout);

    /**
     * 添加对象到redis 里面的list中 redis中的 list 是双向的 所以添加的时候需要注意 rightPush 先进先出 leftPush 先进后出 这里 需要注意
    * @author Andy
    * @date 11:32 2021/8/3
    * @param key:
    * @param list:
    * @param timeout:
    * @return void
    **/
    void addListWithTtl(String key, List list, Long timeout);

    /**
     * 添加对象到redis 里面的list中 redis中的 list 是双向的 所以添加的时候需要注意 rightPush 先进先出 leftPush 先进后出 这里 需要注意
    * @author Andy
    * @date 11:32 2021/8/3
    * @param key:
    * @param value:
    * @param timeout:
    * @return void
    **/
    void lPushWithTtl(String key, Object value, Long timeout);

    /**
     * 添加对象到redis 里面的list中 redis中的 list 是双向的 所以添加的时候需要注意 rightPush 先进先出 leftPush 先进后出 这里 需要注意
    * @author Andy
    * @date 11:32 2021/8/3
    * @param key:
    * @param value:
    * @param timeout:
    * @return void
    **/
    void rPushWithTtl(String key, Object value, Long timeout);

    /**
     * Redis Ltrim 对一个列表进行修剪(trim)，就是说，让列表只保留指定区间内的元素，不在指定区间之内的元素都将被删除。
    * @author Andy
    * @date 11:33 2021/8/3
    * @param key:
    * @param start:
    * @param end:
    * @return void
    **/
    void lTrim(String key, long start, long end);

    /**
     * opsForList().range(key, start, end);  取范围值  redis里面的list下标从0开始 从redis list 里面的获取数据分页
     * @param key utils list 对应的key
     * @param start 开始下标
     * @param end 结束下标
     * @return 返回list给前端
     */
    <T> List<T> getListPage(String key, long start, long end);

    /**
     * 返回列表 key 的长度。
    * @author Andy
    * @date 11:33 2021/8/3
    * @param key:
    * @return java.lang.Long
    **/
    Long lLen(String key);

    /**
     * zIncrby 为有序集 key 的成员 value 的 score 值加上增量 score 。
    * @author Andy
    * @date 11:33 2021/8/3
    * @param key:
    * @param value:
    * @param score:
    * @param timeout:
    * @return void
    **/
    void zIncrbyWithTtl(String key, String value, double score, Long timeout);

    /**
     *  zAdd 将一个 vale 元素及其 score 值加入到有序集 key 当中。
    * @author Andy
    * @date 11:33 2021/8/3
    * @param key:
    * @param vale:
    * @param score:
    * @param timeout:
    * @return void
    **/
    void zAddWithTtl(String key, String vale, double score, Long timeout);

    /**
     * zRange 返回有序集 key 中，指定区间内的成员。
     *      *  其中成员的位置按 score 值递增(从小到大)来排序
    * @author Andy
    * @date 11:33 2021/8/3
    * @param key:
    * @param start:
    * @param end:
    * @return java.util.Set<T>
    **/
    <T> Set<T> zRevrange(String key, long start, long end);

    /**
     * zSet 通过score 获取 最新值和最大值
    * @author Andy
    * @date 11:34 2021/8/3
    * @param key:
    * @param min:
    * @param max:
    * @return java.util.Set<org.springframework.data.redis.core.ZSetOperations.TypedTuple<T>>
    **/
    <T> Set<TypedTuple<T>> zRevrangeWithScores(String key, long min, long max);

    /**
     *  Redis zRem 移除有序集 key 中的一个或多个成员，不存在的成员将被忽略
    * @author Andy
    * @date 11:34 2021/8/3
    * @param key:
    * @param value:
    * @return java.lang.Long
    **/
    Long zRemove(String key, String... value);

    /**
     * Redis Zscore 命令返回有序集中，成员的分数值。 如果成员元素不是有序集 key 的成员，或 key 不存在，返回 nil 。
    * @author Andy
    * @date 11:34 2021/8/3
    * @param key:
    * @param val:
    * @return java.lang.Double
    **/
    Double zScore(String key, Object val);

    /**
     * 返回有序集 key 的数量
    * @author Andy
    * @date 11:34 2021/8/3
    * @param key:
    * @return java.lang.Long
    **/
    Long zCard(String key);

    /**
     * 根据索引值移除区间元素。
     * @param key
     * @param start
     * @param end
     * @return
     */
    Long removeRange(String key, long start, long end);

    /**
     * 获取key的过期时间 秒/单位
     * @param key
     * @return
     */
    Long getExpire(String key);
}