// Path: common/src/main/java/nl/crowndov/displaydirect/common/transport/mqtt/TopicFactory.java
// public class TopicFactory {
// 
//     /**
//      * Generate a topic for subscribe messages
//      * @param stopSytemId An id for the originating stopsystem. If null, will be filled with a wildcard for that level
//      * @return A valid topic name for subscribe messages
//      */
//     public static String subscribe(String stopSytemId) {
//         return stopSystemOrigin(stopSytemId, "subscribe");
//     }
// 
//     /**
//      * Generate a topic for unsubscribe messages
//      * @param stopSytemId An id for the originating stopsystem. If null, will be filled with a wildcard for that level
//      * @return A valid topic name for unsubscribe messages
//      */
//     public static String unsubscribe(String stopSytemId) {
//         return stopSystemOrigin(stopSytemId, "unsubscribe");
//     }
// 
//     /**
//      * Generate a topic for travel information messages
//      * @param stopSytemId An id for the destination stopsystem. If null, will be filled with a wildcard for that level
//      * @return A valid topic name for travel information messages
//      */
//     public static String travelInformation(String stopSytemId) {
//         return stopSystemDestination(stopSytemId, "travel_information");
//     }
// 
//     /**
//      * Generate a topic for subscription response messages
//      * @param stopSytemId An id for the destination stopsystem. If null, will be filled with a wildcard for that level
//      * @return A valid topic name for subscription response messages
//      */
//     public static String subscriptionResponse(String stopSytemId) {
//         return stopSystemDestination(stopSytemId, "subscription_response");
//     }
// 
//     /**
//      * Generate a topic for monitoring messages about stops
//      * @param stopSytemId An id for the object stopsystem. If null, will be filled with a wildcard for that level
//      * @return A valid topic name for monitoring messages
//      */
//     public static String monitoring(String stopSytemId) {
//         return stopSystemDestination(stopSytemId, "monitoring");
//     }
// 
//     /**
//      * Generate a topic for monitoring messages about the distribution function
//      * @return A valid topic name for monitoring messages
//      */
//     public static String monitoring() {
//         return "distribution/monitoring";
//     }
// 
//     private static String stopSystemDestination(String stopSytemId, String category) {
//         return "stopsystem/"+ idOrWildcard(stopSytemId) + "/" + category;
//     }
// 
//     private static String stopSystemOrigin(String stopSytemId, String command) {
//         return command + "/stopsystem/"+ idOrWildcard(stopSytemId);
//     }
// 
//     private static String idOrWildcard(String id) {
//         return id != null ? id : "+";
//     }
// 
// }
// 
// Path: common_client/src/main/java/nl/crowndov/displaydirect/commonclient/domain/SubscriptionBuilder.java
// public class SubscriptionBuilder {
// 
//     public static DisplayDirectMessage.Subscribe subscribe(DisplayParameters display, SystemParameters system) {
//         DisplayDirectMessage.Subscribe.Builder build = DisplayDirectMessage.Subscribe.newBuilder()
//                 .addAllStopCode(system.getStopCodes())
//                 .setDisplayProperties(DisplayDirectMessage.Subscribe.DisplayProperties.newBuilder().setTextCharacters(0))
//                 .setFieldFilter(DisplayDirectMessage.Subscribe.FieldFilter.newBuilder()
//                         .setTripStopStatus(DisplayDirectMessage.Subscribe.FieldFilter.Delivery.ALWAYS)
//                         .setTargetDepartureTime(DisplayDirectMessage.Subscribe.FieldFilter.Delivery.ALWAYS)
//                         .setDestination(DisplayDirectMessage.Subscribe.FieldFilter.Delivery.ALWAYS)
//                         .setLinePublicNumber(DisplayDirectMessage.Subscribe.FieldFilter.Delivery.ALWAYS)
//                         .setTransportType(DisplayDirectMessage.Subscribe.FieldFilter.Delivery.ALWAYS))
//                 .setEmail(system.getEmail())
//                 .setDescription(system.getDescription());
// 
//         return build.build();
//     }
// 
//     public static DisplayDirectMessage.Unsubscribe unsubscribe() {
//         return DisplayDirectMessage.Unsubscribe.newBuilder().setIsPermanent(false).build();
//     }
// }


import nl.crowndov.displaydirect.common.transport.mqtt.TopicFactory;
import nl.crowndov.displaydirect.commonclient.domain.SubscriptionBuilder;
import org.fusesource.hawtbuf.Buffer;
import org.fusesource.hawtbuf.UTF8Buffer;
import org.fusesource.mqtt.client.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.URISyntaxException;
package nl.crowndov.displaydirect.commonclient.mqtt;



/**
 * Copyright 2017 CROW-NDOV
 * <p>
 * This file is subject to the terms and conditions defined in file 'LICENSE.txt', which is part of this source code package.
 */
public class MqttClient {

    private static final Logger LOGGER = LoggerFactory.getLogger(MqttClient.class);

    private MQTT mqtt;
    private final CallbackConnection connection;
    private final byte[] disconnect = SubscriptionBuilder.unsubscribe().toByteArray();
    private final String disconnectTopic;

    public MqttClient(String hostname, String clientId, onClientAction msg) {
        mqtt = new MQTT();
        try {
            mqtt.setHost(hostname);
        } catch (URISyntaxException e) {
            LOGGER.error("Error setting host");
        }
        mqtt.setClientId(clientId);
        mqtt.setCleanSession(true);

        mqtt.setWillMessage(new UTF8Buffer(disconnect));
// Path: common/src/main/java/nl/crowndov/displaydirect/common/transport/mqtt/TopicFactory.java
// public class TopicFactory {
// 
//     /**
//      * Generate a topic for subscribe messages
//      * @param stopSytemId An id for the originating stopsystem. If null, will be filled with a wildcard for that level
//      * @return A valid topic name for subscribe messages
//      */
//     public static String subscribe(String stopSytemId) {
//         return stopSystemOrigin(stopSytemId, "subscribe");
//     }
// 
//     /**
//      * Generate a topic for unsubscribe messages
//      * @param stopSytemId An id for the originating stopsystem. If null, will be filled with a wildcard for that level
//      * @return A valid topic name for unsubscribe messages
//      */
//     public static String unsubscribe(String stopSytemId) {
//         return stopSystemOrigin(stopSytemId, "unsubscribe");
//     }
// 
//     /**
//      * Generate a topic for travel information messages
//      * @param stopSytemId An id for the destination stopsystem. If null, will be filled with a wildcard for that level
//      * @return A valid topic name for travel information messages
//      */
//     public static String travelInformation(String stopSytemId) {
//         return stopSystemDestination(stopSytemId, "travel_information");
//     }
// 
//     /**
//      * Generate a topic for subscription response messages
//      * @param stopSytemId An id for the destination stopsystem. If null, will be filled with a wildcard for that level
//      * @return A valid topic name for subscription response messages
//      */
//     public static String subscriptionResponse(String stopSytemId) {
//         return stopSystemDestination(stopSytemId, "subscription_response");
//     }
// 
//     /**
//      * Generate a topic for monitoring messages about stops
//      * @param stopSytemId An id for the object stopsystem. If null, will be filled with a wildcard for that level
//      * @return A valid topic name for monitoring messages
//      */
//     public static String monitoring(String stopSytemId) {
//         return stopSystemDestination(stopSytemId, "monitoring");
//     }
// 
//     /**
//      * Generate a topic for monitoring messages about the distribution function
//      * @return A valid topic name for monitoring messages
//      */
//     public static String monitoring() {
//         return "distribution/monitoring";
//     }
// 
//     private static String stopSystemDestination(String stopSytemId, String category) {
//         return "stopsystem/"+ idOrWildcard(stopSytemId) + "/" + category;
//     }
// 
//     private static String stopSystemOrigin(String stopSytemId, String command) {
//         return command + "/stopsystem/"+ idOrWildcard(stopSytemId);
//     }
// 
//     private static String idOrWildcard(String id) {
//         return id != null ? id : "+";
//     }
// 
// }
// 
// Path: common_client/src/main/java/nl/crowndov/displaydirect/commonclient/domain/SubscriptionBuilder.java
// public class SubscriptionBuilder {
// 
//     public static DisplayDirectMessage.Subscribe subscribe(DisplayParameters display, SystemParameters system) {
//         DisplayDirectMessage.Subscribe.Builder build = DisplayDirectMessage.Subscribe.newBuilder()
//                 .addAllStopCode(system.getStopCodes())
//                 .setDisplayProperties(DisplayDirectMessage.Subscribe.DisplayProperties.newBuilder().setTextCharacters(0))
//                 .setFieldFilter(DisplayDirectMessage.Subscribe.FieldFilter.newBuilder()
//                         .setTripStopStatus(DisplayDirectMessage.Subscribe.FieldFilter.Delivery.ALWAYS)
//                         .setTargetDepartureTime(DisplayDirectMessage.Subscribe.FieldFilter.Delivery.ALWAYS)
//                         .setDestination(DisplayDirectMessage.Subscribe.FieldFilter.Delivery.ALWAYS)
//                         .setLinePublicNumber(DisplayDirectMessage.Subscribe.FieldFilter.Delivery.ALWAYS)
//                         .setTransportType(DisplayDirectMessage.Subscribe.FieldFilter.Delivery.ALWAYS))
//                 .setEmail(system.getEmail())
//                 .setDescription(system.getDescription());
// 
//         return build.build();
//     }
// 
//     public static DisplayDirectMessage.Unsubscribe unsubscribe() {
//         return DisplayDirectMessage.Unsubscribe.newBuilder().setIsPermanent(false).build();
//     }
// }


// Path: common_client/src/main/java/nl/crowndov/displaydirect/commonclient/mqtt/MqttClient.java
import nl.crowndov.displaydirect.common.transport.mqtt.TopicFactory;
import nl.crowndov.displaydirect.commonclient.domain.SubscriptionBuilder;
import org.fusesource.hawtbuf.Buffer;
import org.fusesource.hawtbuf.UTF8Buffer;
import org.fusesource.mqtt.client.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.URISyntaxException;

package nl.crowndov.displaydirect.commonclient.mqtt;



/**
 * Copyright 2017 CROW-NDOV
 * <p>
 * This file is subject to the terms and conditions defined in file 'LICENSE.txt', which is part of this source code package.
 */
public class MqttClient {

    private static final Logger LOGGER = LoggerFactory.getLogger(MqttClient.class);

    private MQTT mqtt;
    private final CallbackConnection connection;
    private final byte[] disconnect = SubscriptionBuilder.unsubscribe().toByteArray();
    private final String disconnectTopic;

    public MqttClient(String hostname, String clientId, onClientAction msg) {
        mqtt = new MQTT();
        try {
            mqtt.setHost(hostname);
        } catch (URISyntaxException e) {
            LOGGER.error("Error setting host");
        }
        mqtt.setClientId(clientId);
        mqtt.setCleanSession(true);

        mqtt.setWillMessage(new UTF8Buffer(disconnect));
        disconnectTopic = TopicFactory.unsubscribe(clientId);