package com.muyu.data.rabbit;
import com.muyu.common.caffeine.enums.CacheNameEnums;
import com.muyu.common.rabbit.constants.RabbitConstants;
import com.rabbitmq.client.Channel;
import jakarta.annotation.Resource;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * 上线事件监听
 * @Author: WangXin
 * @Name: GoOnlineRabbitConsumer
 */
@Slf4j
@Component
@Setter
public class GoOnlineRabbitConsumer {
    @Resource
    private RedisTemplate<String,String> redisTemplate;
    @Resource
    private CacheManager cacheManager;

    @RabbitListener(queuesToDeclare = {@Queue(RabbitConstants.GO_ONLINE_QUEUE)})
    public void goOnline(String vin, Message message, Channel channel){
        log.info("车辆 {} 上线, 配置信息准备中。。。",vin);
        try {
            // 重复性校验
            Long add = redisTemplate.opsForSet().add(RabbitConstants.GO_ONLINE_QUEUE, message.getMessageProperties().getMessageId());
            if (add>0) {
                addCarCache(vin);
                log.info("车辆 {} 上线, 消息已确认。。。",vin);
            } else {
                log.info("车辆 {} 上线, 消息重复消费，已确认。。。",vin);
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            log.info("车辆 {} 上线, 配置信息已准备完毕。。。",vin);
        } catch (IOException e) {
            try {
                log.warn("车辆 {} 上线, 配置信息准备失败，返回队列，原因：{}", vin, e.getMessage());
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
            } catch (IOException ex) {
                log.warn("车辆 {} 上线, 消息返回队列失败，原因：{}", vin, ex.getMessage());
            }
        }
    }

    /**
     * 车辆上线 - 新增缓存
     */
    public void addCarCache(String vin) {
        // 从Redis中获取缓存信息
        for (String name : CacheNameEnums.getCodes()) {
            String value = redisTemplate.opsForValue().get(name+":"+vin);
            cacheManager.getCache(name).put(vin, value);
            log.info("存储缓存, 缓存分区:[{}], 车辆编码:[{}], 存储值:[{}]", name, vin, value);
        }
        log.info("车辆编码:{},本地缓存完成...",vin);
    }
}
