package com.ruoyi.device.mqtt.handler;

import com.ruoyi.device.mqtt.annotation.ConsumerHandler;
import com.ruoyi.device.mqtt.annotation.ProducerHandler;
import com.ruoyi.device.mqtt.enums.MsgTypeEnum;
import com.ruoyi.device.mqtt.handler.decoder.IDecoder;
import com.ruoyi.device.mqtt.handler.encoder.IEncoder;
import com.ruoyi.device.mqtt.util.MsgHandlerUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * 缓存消费、生产处理器，通过key进行缓存
 *
 * @author lwm
 */
@Component
public class HandlerManager implements ApplicationListener<ContextRefreshedEvent>
{
    private static final Logger log = LoggerFactory.getLogger(HandlerManager.class);

    private static final Map<String, IDecoder> DECODER_MAP = new HashMap<>();
    private static final Map<String, IEncoder<?>> ENCODER_MAP = new HashMap<>();

    /**
     * 监听spring容器启动完成，将所有ConsumerHandler和ProducerHandler缓存起来
     *
     * @param event 上下文
     */
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event)
    {
        ApplicationContext applicationContext = event.getApplicationContext();

        Map<String, Object> consumerHandler = applicationContext.getBeansWithAnnotation(ConsumerHandler.class);
        for (Object bean : consumerHandler.values())
        {
            ConsumerHandler annotation = bean.getClass().getAnnotation(ConsumerHandler.class);
            MsgTypeEnum msgTypeEnum = annotation.msgType();
            DECODER_MAP.put(MsgHandlerUtil.getDecoderKey(msgTypeEnum), (IDecoder) bean);
            log.info("加载消费处理器,key:{},handler:{}", MsgHandlerUtil.getDecoderKey(msgTypeEnum),
                    bean.getClass().getSimpleName());
        }

        Map<String, Object> producerHandler = applicationContext.getBeansWithAnnotation(ProducerHandler.class);
        for (Object bean : producerHandler.values())
        {
            ProducerHandler annotation = bean.getClass().getAnnotation(ProducerHandler.class);
            MsgTypeEnum msgTypeEnum = annotation.msgType();
            ENCODER_MAP.put(MsgHandlerUtil.getEncoderKey(msgTypeEnum), (IEncoder<?>) bean);
            log.info("加载生产处理器,key:{},handler:{}", MsgHandlerUtil.getEncoderKey(msgTypeEnum),
                    bean.getClass().getSimpleName());
        }
    }

    /**
     * 返回已注册解码器；未注册时为 {@code null}，无 unchecked cast。
     */
    public IDecoder getDecoder(String key)
    {
        return DECODER_MAP.get(key);
    }

    /**
     * 获取已注册编码器；未注册时为 {@code null}，无 unchecked cast。
     */
    public IEncoder<?> getEncoder(String key)
    {
        return ENCODER_MAP.get(key);
    }
}
