package co.yixiang.yshop.framework.redis.util;

import co.yixiang.yshop.framework.common.exception.ErrorCode;
import co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;

/**
 * @author pepis
 * @apiNote Redisson 操作工具类
 **/
public class RedissonUtil {
    private final RedissonClient redissonClient;
    Logger logger = LoggerFactory.getLogger(RedissonUtil.class);

    public RedissonUtil(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    /**
     * 向指定key的延时队列中添加任务
     *
     * @param key      延时队列
     * @param v        订单id
     * @param delay    延时时长
     * @param timeUnit 延时单位
     * @param <V>      id类型
     */
    public <V> void delayedOffer(String key, V v, long delay, TimeUnit timeUnit) {
        try {
            RBlockingDeque<Object> blockingDeque = redissonClient.getBlockingDeque(key);
            RDelayedQueue<Object> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
            delayedQueue.offer(v, delay, timeUnit);
            String s = delay + timeUnit.toString();
            logger.info("添加延时队列成功 ，延迟时间：" + s + "订单id: " + v);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    /**
     * 向指定key的延时队列中添加任务
     *
     * @param key      延时队列
     * @param v        订单id
     * @param delay    延时时长
     * @param timeUnit 延时单位
     * @param code     添加失败抛出异常
     * @param <V>      id类型
     */
    public <V> void delayedOfferThrow(String key, V v, long delay, TimeUnit timeUnit, ErrorCode code) {
        try {
            RBlockingDeque<Object> blockingDeque = redissonClient.getBlockingDeque(key);
            RDelayedQueue<Object> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
            delayedQueue.offer(v, delay, timeUnit);
            String s = delay + timeUnit.toString();
            logger.info("添加延时队列成功 ，延迟时间：" + s + "订单id: " + v);
        } catch (Exception e) {
            logger.error(e.getMessage());
            throw ServiceExceptionUtil.exception(code, e.getMessage());
        }
    }

    /**
     * 向指定key的延时队列中删除任务
     *
     * @param key  延时队列
     * @param v    订单id
     * @param code 添加失败抛出异常
     * @param <V>  id类型
     */
    public <V> void delayedRemoveThrow(String key, V v, ErrorCode code) {
        try {
            RBlockingDeque<Object> blockingDeque = redissonClient.getBlockingDeque(key);
            RDelayedQueue<Object> delayedQueue = redissonClient.getDelayedQueue(blockingDeque);
            delayedQueue.remove(v);
            logger.info("删除延时队列成功 ， 订单id: " + v);
        } catch (Exception e) {
            logger.error(e.getMessage());
            throw ServiceExceptionUtil.exception(code, e.getMessage());
        }
    }


}
