package org.apache.seatunnel.datasource.plugin.mqtt;

import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import lombok.Data;

/** @Author Heartsuit @Date 2022-12-11 */
@Data
public class MqttClientService {
    private String HOST;

    private Integer PORT;
    private final String clientId = "Client" + (int) (Math.random() * 100000000);
    private MqttClient mqttClient;

    private String TOPIC;

    public MqttClientService(
            String host,
            Integer port,
            String username,
            String password,
            String topic,
            MqttCallback mqttCallback)
            throws MqttException {
        this.HOST = host;
        this.PORT = port;
        setMqttClient(username, password, topic, mqttCallback);
    }

    public MqttClient getMqttClient(
            String host,
            Integer port,
            String username,
            String password,
            String topic,
            MqttCallback mqttCallback)
            throws MqttException {
        this.HOST = host;
        this.PORT = port;
        setMqttClient(username, password, topic, mqttCallback);
        return mqttClient;
    }

    /**
     * 客户端connect连接mqtt服务器
     *
     * @param username 用户名
     * @param password 密码
     * @param mqttCallback 回调函数
     */
    public void setMqttClient(
            String username, String password, String topic, MqttCallback mqttCallback)
            throws MqttException {
        MqttConnectOptions options = mqttConnectOptions(username, password);
        this.TOPIC = topic;
        /*if (mqttCallback == null) {
            mqttClient.setCallback(new Callback());
        } else {
        }*/
        mqttClient.setCallback(mqttCallback);
        mqttClient.connect(options);
    }

    public void setHOST(String host) {
        this.HOST = host;
    }

    public String getTopic() {
        MqttTopic topic = mqttClient.getTopic(TOPIC);
        return topic.getName();
    }

    /** MQTT连接参数设置 */
    private MqttConnectOptions mqttConnectOptions(String userName, String passWord)
            throws MqttException {
        String url = "tcp://" + HOST + ":" + PORT;
        mqttClient = new MqttClient(url, clientId, new MemoryPersistence());
        MqttConnectOptions options = new MqttConnectOptions();
        options.setUserName(userName);
        options.setPassword(passWord.toCharArray());
        options.setConnectionTimeout(10); // /默认：30
        options.setAutomaticReconnect(true); // 默认：false
        options.setCleanSession(false); // 默认：true
        // options.setKeepAliveInterval(20);//默认：60
        return options;
    }

    /** 关闭MQTT连接 */
    public void close() throws MqttException {
        mqttClient.close();
        mqttClient.disconnect();
    }

    /** 向某个主题发布消息 默认qos：1 */
    public void pub(String topic, String msg) throws MqttException {
        MqttMessage mqttMessage = new MqttMessage();
        // mqttMessage.setQos(2);
        mqttMessage.setPayload(msg.getBytes());
        MqttTopic mqttTopic = mqttClient.getTopic(topic);
        MqttDeliveryToken token = mqttTopic.publish(mqttMessage);
        token.waitForCompletion();
    }

    public void pub(String msg) throws MqttException {
        MqttMessage mqttMessage = new MqttMessage();
        // mqttMessage.setQos(2);
        mqttMessage.setPayload(msg.getBytes());
        MqttTopic mqttTopic = mqttClient.getTopic(TOPIC);
        MqttDeliveryToken token = mqttTopic.publish(mqttMessage);
        token.waitForCompletion();
    }

    /**
     * 向某个主题发布消息
     *
     * @param topic: 发布的主题
     * @param msg: 发布的消息
     * @param qos: 消息质量 Qos：0、1、2
     */
    public void pub(String topic, String msg, int qos) throws MqttException {
        MqttMessage mqttMessage = new MqttMessage();
        mqttMessage.setQos(qos);
        mqttMessage.setPayload(msg.getBytes());
        MqttTopic mqttTopic = mqttClient.getTopic(topic);
        MqttDeliveryToken token = mqttTopic.publish(mqttMessage);
        token.waitForCompletion();
    }

    public void pub(String msg, int qos) throws MqttException {
        MqttMessage mqttMessage = new MqttMessage();
        mqttMessage.setQos(qos);
        mqttMessage.setPayload(msg.getBytes());
        MqttTopic mqttTopic = mqttClient.getTopic(TOPIC);
        MqttDeliveryToken token = mqttTopic.publish(mqttMessage);
        token.waitForCompletion();
    }

    /**
     * 订阅某一个主题 ，此方法默认的的Qos等级为：1
     *
     * @param topic 主题
     */
    public void sub(String topic) throws MqttException {
        mqttClient.subscribe(topic);
    }

    public void sub() throws MqttException {
        mqttClient.subscribe(TOPIC);
    }

    /**
     * 订阅某一个主题，可携带Qos
     *
     * @param topic 所要订阅的主题
     * @param qos 消息质量：0、1、2
     */
    public void sub(String topic, int qos) throws MqttException {
        mqttClient.subscribe(topic, qos);
    }

    public void sub(int qos) throws MqttException {
        mqttClient.subscribe(TOPIC, qos);
    }
}
