package com.yonge.redisson;

import com.yonge.cooleshow.biz.dal.redisson.RedissonMessageService;
import com.yonge.cooleshow.biz.dal.service.LiveRoomService;
import com.yonge.cooleshow.biz.dal.wrapper.liveroom.LiveRoomWrapper;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * Redisson消息发布订阅服务监听
 */
@Slf4j
@Service
public class RedissonTopicListener implements ApplicationRunner, Ordered {
 
    @Autowired
    private RedissonMessageService redissonMessageService;
    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private LiveRoomService liveRoomService;
 
    @Override
    public void run(ApplicationArguments args) {

        if (Objects.nonNull(redissonMessageService)) {

            redissonMessageService.subscribe(RedissonMessageService.TOPIC_MESSAGE, (message) -> {
                log.info("RedissonMessageService subscribe message={}", message);
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    log.error("RedissonMessageService subscribe sleep error", e);
                }

                RLock lock = redissonClient.getLock(RedissonMessageService.LIVE_ROOM_MEMBER_LOCK + message);
                try {
                    if (lock.tryLock()) {
                        // 缓存JoinRoom用户信息到redis
                        RBucket<Object> bucket = redissonClient.getBucket(RedissonMessageService.LIVE_ROOM_MEMBER + message);
                        if (!bucket.isExists()) {
                            return;
                        }
                        Integer times = (Integer) bucket.get();
                        bucket.delete();

                        LiveRoomWrapper.LiveRoomVo liveRoomVo = liveRoomService.queryRoomInfo(message);
                        if (Objects.isNull(liveRoomVo)) {
                            return;
                        }
                        try {
                            liveRoomService.setGroupMemberDefinedData(liveRoomVo,liveRoomVo.getLookNum(),liveRoomVo.getTotalLookNum());
                        } catch (Exception e) {
                            log.error("RedissonMessageService subscribe setGroupMemberDefinedData error", e);
                            if (times>=3) {
                                return;
                            }
                            bucket.set(times +1, 30, TimeUnit.MINUTES);
                        }
                        redissonMessageService.publish(RedissonMessageService.TOPIC_MESSAGE, message);
                    }
                } finally {
                    if (lock.getHoldCount() != 0 && lock.isHeldByCurrentThread()) {
                        lock.unlock();
                    }
                }


            });
            log.info("---> RedissonMessageService subscribe success");
        }
    }

    @Override
    public int getOrder() {
        return 1;
    }
}
