package cn.reghao.autodop.common.log;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import cn.reghao.autodop.common.mqtt.DefaultMqttClient;
import cn.reghao.autodop.common.msg.Message;
import cn.reghao.autodop.common.msg.MsgQueue;
import cn.reghao.autodop.common.msg.pub.PubMsg;
import cn.reghao.autodop.common.msg.pub.clazz.NodePubClazz;
import cn.reghao.autodop.common.msg.pub.dto.node.NodeLogDTO;
import cn.reghao.jdkutil.machine.MachineId;
import cn.reghao.jdkutil.serializer.JsonConverter;
import org.eclipse.paho.client.mqttv3.MqttException;

/**
 * @author reghao
 * @date 2021-06-08 19:37:21
 */
public class MqttAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
    private final String appId;
    private final String topic;
    private final DefaultMqttClient mqttClient;

    public MqttAppender(String appId, DefaultMqttClient mqttClient) {
        this.appId = appId;
        this.topic = MsgQueue.dmasterTopic();
        this.mqttClient = mqttClient;
    }

    @Override
    public void start() {
        super.start();
    }

    @Override
    public void stop() {
        super.stop();
    }

    @Override
    protected void append(ILoggingEvent event) {
        NodeLogDTO nodeLogDTO = nodeLogDTO(event);
        String jsonPayload = JsonConverter.objectToJson(nodeLogDTO);
        PubMsg pubMsg = PubMsg.pubMsg(NodePubClazz.class.getSimpleName(), NodePubClazz.log.name(), jsonPayload);
        Message message = Message.pubMessage(pubMsg);
        try {
            mqttClient.pub(topic, 1, JsonConverter.objectToJson(message));
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    private NodeLogDTO nodeLogDTO(ILoggingEvent event) {
        NodeLogDTO nodeLogDTO = new NodeLogDTO();
        nodeLogDTO.setMachineId(MachineId.id());
        nodeLogDTO.setAppId(appId);
        nodeLogDTO.setTimestamp(event.getTimeStamp());
        nodeLogDTO.setLevel(event.getLevel().toString());
        nodeLogDTO.setThreadName(event.getThreadName());
        nodeLogDTO.setLoggerName(event.getLoggerName());
        nodeLogDTO.setMessage(event.getFormattedMessage());
        return nodeLogDTO;
    }
}
