package com.inspect.partrolresult.service;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class RedissonDelayQueueServiceImpl<T> implements DelayQueueService<T> {

    @Resource
    private RedissonClient redissonClient;

    /**
     * 工作机制如下：
     * 1. 先往延迟池delayedQueue存入了一个 ZSET + HASH（Redis结构），并设置了时间戳
     * 2. Redisson 后台调度器线程会在数据到期时将它从延迟 ZSET 中移动到目标的 blockingQueue 中。
     * @param queueName
     * @param payload
     * @param delay
     * @param timeUnit
     */
    @Override
    public void submitRequest(String queueName, T payload, long delay, TimeUnit timeUnit) {
        RBlockingQueue<T> blockingQueue = redissonClient.getBlockingQueue(queueName);
        RDelayedQueue<T> delayedQueue = redissonClient.getDelayedQueue(blockingQueue);

        delayedQueue.offer(payload, delay, timeUnit);
        log.info("Submit Delay Queue Task To: {}, Delay: {} {}", queueName, delay, timeUnit);
    }

    @Override
    public boolean removeRequest(String queueName, T payload) {
        RBlockingQueue<T> blockingQueue = redissonClient.getBlockingQueue(queueName);
        RDelayedQueue<T> delayedQueue = redissonClient.getDelayedQueue(blockingQueue);

        return delayedQueue.remove(payload);
    }

    @Override
    public boolean containRequest(String queueName, T payload) {
        RBlockingQueue<T> blockingQueue = redissonClient.getBlockingQueue(queueName);
        RDelayedQueue<T> delayedQueue = redissonClient.getDelayedQueue(blockingQueue);

        return delayedQueue.contains(payload);
    }
}

