package com.ruoyi.device.mqtt.handler;

import com.ruoyi.device.mqtt.annotation.JsonCmdDownHandler;
import com.ruoyi.device.mqtt.annotation.JsonCmdUpHandler;
import com.ruoyi.device.mqtt.enums.CmdTypeEnum;
import com.ruoyi.device.mqtt.handler.decoder.json.IJsonCmdUpHandler;
import com.ruoyi.device.mqtt.handler.encoder.json.IJsonCmdDownHandler;
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;

/**
 * 按 {@link CmdTypeEnum} 将 JSON 上行/下行分发
 *
 * @author lwm
 */
@Component
public class JsonCmdHandlerManager implements ApplicationListener<ContextRefreshedEvent>
{
    private static final Logger log = LoggerFactory.getLogger(JsonCmdHandlerManager.class);

    private final Map<String, IJsonCmdUpHandler> UP_HANDLER_BY_UP_KEY = new HashMap<>();
    private final Map<String, IJsonCmdUpHandler> UP_HANDLER_BY_BASE_KEY = new HashMap<>();

    private final Map<String, IJsonCmdDownHandler> DOWN_HANDLER_BY_DOWN_KEY = new HashMap<>();
    private final Map<String, IJsonCmdDownHandler> DOWN_HANDLER_BY_BASE_KEY = new HashMap<>();

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

        Map<String, Object> jsonCmdUpHandler = ctx.getBeansWithAnnotation(JsonCmdUpHandler.class);
        for (Object bean : jsonCmdUpHandler.values())
        {
            JsonCmdUpHandler annotation = bean.getClass().getAnnotation(JsonCmdUpHandler.class);
            CmdTypeEnum cmdTypeEnum = annotation.cmdType();
            UP_HANDLER_BY_UP_KEY.put(cmdTypeEnum.getCmdUpType(), (IJsonCmdUpHandler) bean);
            UP_HANDLER_BY_BASE_KEY.put(cmdTypeEnum.getCmdType(), (IJsonCmdUpHandler) bean);
            log.info("加载 JSON 命令上行处理器 upKey={}, baseKey={}, handler={}",
                    cmdTypeEnum.getCmdUpType(), cmdTypeEnum.getCmdType(), bean.getClass().getSimpleName());
        }

        Map<String, Object> jsonCmdDownHandler = ctx.getBeansWithAnnotation(JsonCmdDownHandler.class);
        for (Object bean : jsonCmdDownHandler.values())
        {
            JsonCmdDownHandler annotation = bean.getClass().getAnnotation(JsonCmdDownHandler.class);
            CmdTypeEnum cmdTypeEnum = annotation.cmdType();
            DOWN_HANDLER_BY_DOWN_KEY.put(cmdTypeEnum.getCmdDownType(), (IJsonCmdDownHandler) bean);
            DOWN_HANDLER_BY_BASE_KEY.put(cmdTypeEnum.getCmdType(), (IJsonCmdDownHandler) bean);
            log.info("加载 JSON 命令下行处理器 downKey={}, baseKey={}, handler={}",
                    cmdTypeEnum.getCmdDownType(), cmdTypeEnum.getCmdType(), bean.getClass().getSimpleName());
        }
    }

    /**
     * 按 upKey 获取上行处理器
     */
    public IJsonCmdUpHandler getUpHandlerByUpKey(String upKey)
    {
        return UP_HANDLER_BY_UP_KEY.get(upKey);
    }

    /**
     * 按 baseKey 获取上行处理器
     */
    public IJsonCmdUpHandler getUpHandlerByBaseKey(String baseKey)
    {
        return UP_HANDLER_BY_BASE_KEY.get(baseKey);
    }

    /**
     * 按 downKey 获取下行处理器
     */
    public IJsonCmdDownHandler getDownHandlerByDownKey(String downKey)
    {
        return DOWN_HANDLER_BY_DOWN_KEY.get(downKey);
    }

    /**
     * 按 baseKey 获取下行处理器
     */
    public IJsonCmdDownHandler getDownHandlerByBaseKey(String baseKey)
    {
        return DOWN_HANDLER_BY_BASE_KEY.get(baseKey);
    }
}
