package cn.reghao.autodop.dagent.spring;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import cn.reghao.autodop.common.log.Appenders;
import cn.reghao.autodop.common.machine.Machine;
import cn.reghao.autodop.common.mqtt.DefaultMqttClient;
import cn.reghao.autodop.common.msg.MsgQueue;
import cn.reghao.autodop.common.msg.pub.dto.node.constant.AppId;
import cn.reghao.autodop.dagent.machine.NodeClazzPubImpl;
import cn.reghao.autodop.dagent.rpc.RpcListener;
import cn.reghao.autodop.common.log.LoggerConfig;
import cn.reghao.jdkutil.machine.MachineId;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;

/**
 * TODO 无法处理 kill -9 和机器断电的情况
 *
 * @author reghao
 * @date 2021-04-01 11:36:51
 */
@Slf4j
@Configuration
public class DagentLifecycle implements ApplicationRunner, DisposableBean {
    private final DefaultMqttClient mqttClient;
    private final RpcListener rpcListener;
    private final NodeClazzPubImpl nodeClazzPub;

    public DagentLifecycle(DefaultMqttClient mqttClient, RpcListener rpcListener, Machine machine) {
        this.mqttClient = mqttClient;
        this.rpcListener = rpcListener;
        this.nodeClazzPub = new NodeClazzPubImpl(mqttClient, machine);
        initLogger();
    }

    private void initLogger() {
        List<Appender<ILoggingEvent>> appenders = new ArrayList<>();
        appenders.add(Appenders.mqttAppender(AppId.dagent.name(), mqttClient));
        LoggerConfig.initLogger(appenders);
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        subTopic();
        pubDagentStart();
        pubDagentHeartbeat();
    }

    @Override
    public void destroy() {
        pubDagentShutdown();
    }

    private void subTopic() throws MqttException {
        String topic = MsgQueue.dagentTopic(MachineId.id());
        mqttClient.sub(topic, rpcListener);
    }

    private void pubDagentStart() {
        nodeClazzPub.nodeStart();
    }

    private void pubDagentHeartbeat() {
        nodeClazzPub.nodeHeartbeat();
    }

    private void pubDagentShutdown() {
        nodeClazzPub.nodeShutdown();
        log.info("Dagent 停止");
    }
}
