package com.inspect.mqtt;

import javax.annotation.PostConstruct;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class MQTTUtil implements IMQTTUtil {
    @Value("${mqtt.ip}")
    protected String ip;
    @Value("${mqtt.clientId}")
    protected String clientId;
    @Value("${mqtt.user}")
    protected String user;
    @Value("${mqtt.pwd}")
    protected String pwd;
    @Value("${mqtt.topicFilters}")
    protected String topicFilters;
    MqttClient client = null;
    private Long id = 0L;

    public Long getId() {
        return this.id;
    }

    @PostConstruct
    public void mqttUtil() {
        log.info("mqttUtil start!!!");
    }

    public void subscribe(String[] topicFilters, int[] qos) {
        try {
            log.info("subscribe topicFilters: {}, qos: {}", topicFilters, qos);
            client.subscribe(topicFilters, qos);
        } catch (MqttException e) {
            log.info("reason: {}", e.getReasonCode());
            log.info("msg: {}", e.getMessage());
            log.info("loc: {}", e.getLocalizedMessage());
            log.info("cause: {}", e.getCause());
            log.info("exception: {}", e.getMessage());
            e.printStackTrace();
        }

    }

    public void connect(String broker, String clientId, String userName, String password, MqttCallback callback) {
        MemoryPersistence persistence = new MemoryPersistence();
        try {
            client = new MqttClient(broker, clientId, persistence);
            MqttConnectOptions connOpts = new MqttConnectOptions();
            connOpts.setUserName(userName);
            connOpts.setPassword(password.toCharArray());
            connOpts.setCleanSession(true);
            client.setCallback(callback);
            log.info("Connecting to mqtt broker: {}", broker);
            client.connect(connOpts);
            log.info("Connected to mqtt broker");
        } catch (MqttException e) {
            System.out.println("reason: " + e.getReasonCode());
            System.out.println("msg: " + e.getMessage());
            System.out.println("loc: " + e.getLocalizedMessage());
            System.out.println("cause: " + e.getCause());
            System.out.println("exception: " + e);
            e.printStackTrace();
        }

    }

    public void disconnect() {
        try {
            log.info("Disconnect mqtt broker");
            client.disconnect();
            client.close();
        } catch (MqttException e) {
            System.out.println("reason: " + e.getReasonCode());
            System.out.println("msg: " + e.getMessage());
            System.out.println("loc: " + e.getLocalizedMessage());
            System.out.println("cause: " + e.getCause());
            System.out.println("exception: " + e);
            e.printStackTrace();
        }

    }

    public void publish2(int qos, String pubTopic, String content) {
    }

    public boolean publish(int qos, String pubTopic, String content) {
        try {
            MqttMessage message = new MqttMessage(content.getBytes());
            message.setQos(qos);
            log.info("Publish mqtt broker");
            client.publish(pubTopic, message);
            return true;
        } catch (MqttException e) {
            System.out.println("reason: " + e.getReasonCode());
            System.out.println("msg: " + e.getMessage());
            System.out.println("loc: " + e.getLocalizedMessage());
            System.out.println("cause: " + e.getCause());
            System.out.println("exception: " + e);
            e.printStackTrace();
            return false;
        }
    }
}
