package fr.icam.emit.listeners;

import java.util.HashMap;
import java.util.Map;

import org.bson.Document;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
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 com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoIterable;

public class MqttListener extends MqttClient implements MqttCallback {

	private static Map<Long, MqttListener> instances = new HashMap<Long, MqttListener>(124);

	public static void start(Long id, String uri, String uuid, String topic, MongoDatabase database) throws MqttException {
		System.out.println("[MongoDB] starting " + id + " to '" + topic + "' in " + uuid);
		MqttListener listener = instances.get(id);
		if (listener == null) {
			listener = new MqttListener(id, uri, uuid, topic, database);
			instances.put(id, listener);
		}
		listener.subscribe(topic);
		System.out.println("[MongoDB] started " + id + " to '" + topic + "' in " + uuid);
	}
	
	public static void stop(Long id) throws MqttException {
		System.out.println("[MongoDB] stopping " + id);
		MqttListener listener = instances.get(id);
		if (listener == null) {
			throw new MqttException(new NullPointerException("No MQTT Client found for feature id = '" + id.toString() +"'"));
		}
		listener.disconnect();
		instances.remove(id);
		System.out.println("[MongoDB] stopped " + id);
	}
	
	private MongoCollection<Document> collection;
	
	private MqttListener(Long id, String uri, String uuid, String topic, MongoDatabase db) throws MqttException {
		super(uri, uuid, new MemoryPersistence());
		System.out.println("[MongoDB] creating " + uuid);
		db.createCollection(uuid);
		this.collection = db.getCollection(uuid);
		MqttConnectOptions options = new MqttConnectOptions();
		options.setCleanSession(true);
		this.connect(options);
		this.setCallback(this);
		System.out.println("[MongoDB] created " + uuid);
		System.out.println("[MongoDB] existing " + this.doExists(uuid, db));
	}

	private boolean doExists(final String uuid, MongoDatabase db) {
	     MongoIterable<String> names = db.listCollectionNames();
	    for (final String name : names) {
	        if (name.equalsIgnoreCase(uuid)) {
	            return true;
	        }
	    }
	    return false;
	}
	
	public void connectionLost(Throwable throwable) {
		System.out.println("[MongoDB] failure: ");
		throwable.printStackTrace();
	}

	public void deliveryComplete(IMqttDeliveryToken token) {
		
	}

	public void messageArrived(String topic, MqttMessage message) throws Exception {
		Double value = Double.valueOf(new String(message.getPayload()));
		Document document = new Document();
		// document.append("type", topic);
		document.append("value", value);
		document.append("time", System.currentTimeMillis()); /* FIXME */
		collection.insertOne(document);
		System.out.println("[MongoDB] insert: " + document.toJson());
	}

}

@@ -576,49 +576,8 @@
 ase;
-%0Aimport com.mongodb.client.MongoIterable;
 %0A%0Apu
@@ -862,93 +862,8 @@
 n %7B%0A
-%09%09System.out.println(%22%5BMongoDB%5D starting %22 + id + %22 to '%22 + topic + %22' in %22 + uuid);%0A
 %09%09Mq
@@ -1062,92 +1062,8 @@
 c);%0A
-%09%09System.out.println(%22%5BMongoDB%5D started %22 + id + %22 to '%22 + topic + %22' in %22 + uuid);%0A
 %09%7D%0A%09
@@ -1124,58 +1124,8 @@
 n %7B%0A
-%09%09System.out.println(%22%5BMongoDB%5D stopping %22 + id);%0A
 %09%09Mq
@@ -1366,57 +1366,8 @@
 d);%0A
-%09%09System.out.println(%22%5BMongoDB%5D stopped %22 + id);%0A
 %09%7D%0A%09
@@ -1576,60 +1576,8 @@
 ));%0A
-%09%09System.out.println(%22%5BMongoDB%5D creating %22 + uuid);%0A
 %09%09db
@@ -1791,410 +1791,10 @@
 );%0A%09
-%09System.out.println(%22%5BMongoDB%5D created %22 + uuid);%0A%09%09System.out.println(%22%5BMongoDB%5D existing %22 + this.doExists(uuid, db));%0A%09%7D%0A%0A%09private boolean doExists(final String uuid, MongoDatabase db) %7B%0A%09     MongoIterable%3CString%3E names = db.listCollectionNames();%0A%09    for (final String name : names) %7B%0A%09        if (name.equalsIgnoreCase(uuid)) %7B%0A%09            return true;%0A%09        %7D%0A%09    %7D%0A%09    return false;%0A%09%7D%0A%09
+%7D%0A
 %0A%09pu
@@ -1845,53 +1845,8 @@
 ) %7B%0A
-%09%09System.out.println(%22%5BMongoDB%5D failure: %22);%0A
 %09%09th
@@ -2132,45 +2132,8 @@
 ();%0A
-%09%09// document.append(%22type%22, topic);%0A
 %09%09do
@@ -2268,74 +2268,9 @@
 t);%0A
-%09%09System.out.println(%22%5BMongoDB%5D insert: %22 + document.toJson());%0A
 %09%7D%0A%0A%7D
-%0A

remove standard outputs from mongodb operations of mqtt clients