package com.ema.common.tools.redis;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Set;

/**
 * Redis服务
 *
 * @author LJ
 */
@Validated
public interface RedisService {

    /**
     * 获取redisTemplate
     *
     * @return
     */
    RedisTemplate<String, Object> getRredisTemplate();

    /**
     * 设置缓存
     *
     * @param prefix
     * @param key
     * @param value
     * @param expire 过期时间,小于等于0不过期（秒）
     * @return
     */
    boolean set(String prefix, @NotBlank String key, @NotNull Object value, long expire);

    /**
     * 设置已有缓存，不更新原有过期时间
     *
     * @param prefix
     * @param key
     * @param value
     * @return
     */
    boolean set(String prefix,@NotBlank  String key,@NotNull Object value);

    /**
     * 获取缓存字符串
     *
     * @param prefix
     * @param key
     * @return
     */
    String getStr(String prefix,@NotBlank  String key);

    /**
     * 获取缓存Object
     *
     * @param prefix
     * @param key
     * @return
     */
    Object getObj(String prefix,@NotBlank  String key);

    /**
     * 获取缓存Bean
     *
     * @param prefix
     * @param key
     * @param clazz
     * @return
     */
    <T> T getBean(String prefix, @NotBlank String key, @NotNull Class<T> clazz);

    /**
     * 获取缓存集合
     *
     * @param prefix
     * @param key
     * @param clazz
     * @return
     */
    <T> List<T> getList(String prefix, @NotBlank String key, @NotNull Class<T> clazz);

    /**
     * 判断缓存是否存在
     *
     * @param prefix
     * @param key
     * @return
     */
    boolean exists(String prefix, @NotBlank String key);

    /**
     * 删除
     *
     * @param prefix
     * @param key
     */
    void delete(String prefix, @NotBlank String key);

    /**
     * 批量删除
     *
     * @param redisKeys
     */
    void delete(@NotBlank Set<String> redisKeys);

    /**
     * 按规则批量删除
     *
     * @param pattern
     */
    void deletePattern(@NotBlank String pattern);

    /**
     * 更新缓存失效时长
     *
     * @param prefix
     * @param key
     * @param timeout 失效时长(单位秒)
     * @return
     */
    void expire(String prefix, @NotBlank String key, long timeout);

    /**
     * 将键的整数值增加1
     *
     * @param prefix
     * @param key
     * @return
     */
    Long incr(String prefix, @NotBlank String key);

    /**
     * 将键的整数值减1
     *
     * @param prefix
     * @param key
     * @return
     */
    Long decr(String prefix, @NotBlank String key);
    
    /**
     * 长度限制
     *
     * @param prefix
     * @param key
     * @param start
     * @param end
     * @return
     */
    void trim(String prefix,@NotBlank  String key,long start,long end);


    /**
     * 加锁（带UUID防误删）
     * @param lockKey 锁key
     * @param expire 过期时间（毫秒）
     * @return lockValue 锁值
     */
    String tryLock(String lockKey, long expire);


    /**
     * 解锁（Lua脚本保证原子性）
     * @param lockKey
     * @param lockValue
     * @return
     */
    boolean unlock(String lockKey, String lockValue);

    /**
     * 续期（看门狗机制）
     * @param lockKey
     * @param lockValue
     * @param expire 过期时间（毫秒）
     * @return
     */
    boolean renewLock(String lockKey, String lockValue, long expire);
}
