package com.qmth.teachcloud.common.util;

import com.qmth.teachcloud.common.bean.dto.MqDto;
import com.qmth.teachcloud.common.contant.SystemConstant;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @Description: redis util
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2020/4/15
 */
@Component
public class RedisUtil {

    @Resource
    RedisTemplate<String, Object> redisTemplate;

    /**
     * 获取用户会话信息
     *
     * @param sessionId
     * @return
     */
    public Object getUserSession(String sessionId) {
        return redisTemplate.opsForValue().get(SystemConstant.SESSION + sessionId);
    }

    /**
     * 删除用户会话缓存
     *
     * @param sessionId
     */
    public void deleteUserSession(String sessionId) {
        redisTemplate.delete(SystemConstant.SESSION + sessionId);
    }

    /**
     * 设置用户session信息
     *
     * @param sessionId
     * @param o
     * @param time
     */
    public void setUserSession(String sessionId, Object o, long time) {
        redisTemplate.opsForValue().set(SystemConstant.SESSION + sessionId, o, time, TimeUnit.SECONDS);
    }

    /**
     * 获取过期时间
     *
     * @param sessionId
     * @return
     */
    public Long getUserSessionExpire(String sessionId) {
        return redisTemplate.opsForValue().getOperations().getExpire(SystemConstant.SESSION + sessionId);
    }

    /**
     * 批量获取key的value
     *
     * @param keys
     * @return
     */
    public List<?> multiGet(Set keys) {
        return redisTemplate.opsForValue().multiGet(keys);
    }

    /**
     * 获取key like
     *
     * @param key
     * @return
     */
    public Set<?> getKeyPatterns(String key) {
        if (Objects.nonNull(key)) {
            return redisTemplate.keys(key);
        } else {
            return null;
        }
    }

    /**
     * 设置hash
     *
     * @param key
     * @param hashKey
     * @param hashValue
     */
    public void set(String key, String hashKey, Object hashValue) {
        redisTemplate.opsForHash().put(key, hashKey, hashValue);
    }

    /**
     * 获取hash
     *
     * @param key
     * @param hashKey
     * @return
     */
    public Object get(String key, String hashKey) {
        return redisTemplate.opsForHash().get(key, hashKey);
    }

    /**
     * hash删除
     *
     * @param key
     * @param hashKey
     */
    public void delete(String key, String hashKey) {
        redisTemplate.opsForHash().delete(key, hashKey);
    }

    /**
     * 获取hash大小
     *
     * @param key
     * @return
     */
    public Long getHashSize(String key) {
        return redisTemplate.opsForHash().size(key);
    }

    /**
     * 获取hash map
     *
     * @param key
     * @return
     */
    public Map getHashEntries(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * 分布式锁
     *
     * @param key
     * @param timeout SECONDS
     * @return
     */
    public boolean lock(String key, long timeout) {
        long expireAt = System.currentTimeMillis() + (timeout * 1000) + 1;
        return redisTemplate.opsForValue().setIfAbsent(key, expireAt, timeout, TimeUnit.SECONDS);
    }

    /**
     * 删除锁
     *
     * @param key
     * @return
     */
    public void releaseLock(String key) {
        redisTemplate.expire(key, 100, TimeUnit.MILLISECONDS);
    }

    /**
     * 设置缓存
     *
     * @param key
     * @param o
     */
    public void set(String key, Object o) {
        redisTemplate.opsForValue().set(key, o);
    }

    /**
     * 设置缓存
     *
     * @param key
     * @param o
     * @param time
     * @param timeUnit
     */
    public void set(String key, Object o, long time, TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, o, time, timeUnit);
    }

    /**
     * 设置缓存
     *
     * @param key
     * @param o
     * @param time SECONDS
     */
    public void set(String key, Object o, long time) {
        set(key, o, time, TimeUnit.SECONDS);
    }

    /**
     * 获取缓存
     *
     * @param key
     * @return
     */
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 删除缓存
     *
     * @param key
     * @return
     */
    public void delete(String key) {
        redisTemplate.expire(key, 0, TimeUnit.SECONDS);
    }

    /**
     * 保存hash结构
     *
     * @param key
     * @param map
     */
    public void setForHash(String key, Map<String, Object> map) {
        redisTemplate.opsForHash().putAll(key, map);
    }

    /**
     * 保存list
     *
     * @param key
     * @param Object
     */
    public void setForLeftList(String key, Object Object) {
        redisTemplate.opsForList().leftPush(key, Object);
    }

    /**
     * 获取list
     *
     * @param key
     */
    public Object getForRightList(String key) {
        return redisTemplate.opsForList().rightPop(key, 0, TimeUnit.SECONDS);
    }

    /**
     * 设置过期时间（秒）
     *
     * @param key
     * @param timeOutSecond
     */
    public void expire(String key, int timeOutSecond) {
        redisTemplate.expire(key, timeOutSecond, TimeUnit.SECONDS);
    }

    /**
     * 设置过期时间
     *
     * @param key
     * @param timeOut
     */
    public void expire(String key, long timeOut, TimeUnit timeUnit) {
        redisTemplate.expire(key, timeOut, timeUnit);
    }

    /**
     * 发送消息
     *
     * @param topic
     * @param mqDto
     */
    public void sendMessage(String topic, MqDto mqDto) {
        mqDto.setAck(SystemConstant.DELIVERED_ACK_TYPE);
        redisTemplate.convertAndSend(topic, JacksonUtil.parseJson(mqDto));
        this.set(SystemConstant.MQ_TOPIC_BUFFER_LIST, mqDto.getId(), mqDto);
    }
}