package com.ruoyi.system.core.mqtt;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.system.core.ClientExecute;
import com.ruoyi.system.core.ClientExecuteFactory;
import com.ruoyi.system.core.deviceEntity.ProductEntity;
import com.ruoyi.system.core.deviceEntity.ProductEntityFactory;
import com.ruoyi.system.mapper.SysDeviceMapper;
import com.ruoyi.system.util.SpringContextHolder;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;

/**
 * 常规MQTT回调函数
 */
public class MqttClientCallback implements MqttCallback {

    /**
     * 系统的mqtt客户端id
     */
    private String mqttClientId;

    public MqttClientCallback(String mqttClientId) {
        this.mqttClientId = mqttClientId;
    }


    /**
     * MQTT 断开连接会执行此方法
     */
    @Override
    public void connectionLost(Throwable throwable) {
        //log.error(throwable.getMessage(), throwable);
    }

    /**
     * publish发布成功后会执行到这里
     */
    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
    }

    /**
     * subscribe订阅后得到的消息会执行到这里
     */
    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
        try {
            String[] split = topic.split("/");
            System.err.println(new String(message.getPayload(), StandardCharsets.UTF_8));
            common(split[2], message);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Transactional
    public void common(String deviceNo, MqttMessage message) {
        JSONObject jsonObject = JSON.parseObject(new String(message.getPayload(), StandardCharsets.UTF_8));
        jsonObject.put("inputs", jsonObject.getJSONArray("inputs").toJSONString());
        DefProtocol defProtocol = JSON.parseObject(jsonObject.toJSONString(), DefProtocol.class);
        SysDeviceMapper deviceMapper = SpringContextHolder.getBean(SysDeviceMapper.class);
        ProductEntityFactory entityFactory = SpringContextHolder.getBean(ProductEntityFactory.class);
        ClientExecuteFactory clientExecuteFactory = SpringContextHolder.getBean(ClientExecuteFactory.class);
        deviceMapper.selectByDeviceNo(deviceNo).subscribe(x -> {
            ProductEntity productEntity = entityFactory.getProductEntity(x.getDeviceType());
            ClientExecute clientExecute = clientExecuteFactory.getClientExecute(x.getConnectionType());
            if (defProtocol.getFunctionId().contains("info_")) {
                productEntity.info(defProtocol, clientExecute, x);
            } else {
                productEntity.put(defProtocol, clientExecute, x);
            }
        });
    }


}