package no.ntnu.okse.protocol.mqtt;

import io.moquette.interception.InterceptHandler;
import io.moquette.interception.messages.*;
import no.ntnu.okse.core.messaging.Message;
import no.ntnu.okse.core.subscription.Publisher;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import org.mockito.*;

import static org.testng.Assert.*;


public class MQTTServerTest {

	enum Status {
		CONNECT,
		DISCONNECT,
		PUBLISH,
		SUBSCRIBE,
		UNSUBSCRIBE
	}

	private static Status status;
	private static InterceptAbstractMessage interceptMessage;

	private static final class MockObserver implements InterceptHandler {
		@Override
		public void onConnect(InterceptConnectMessage interceptConnectMessage) {
			status = Status.CONNECT;
		}

		@Override
		public void onDisconnect(InterceptDisconnectMessage interceptDisconnectMessage) {
			status = Status.DISCONNECT;
		}

		@Override
		public void onPublish(InterceptPublishMessage interceptPublishMessage) {
			status = Status.PUBLISH;
		}

		@Override
		public void onSubscribe(InterceptSubscribeMessage interceptSubscribeMessage) {
			status = Status.SUBSCRIBE;
		}

		@Override
		public void onUnsubscribe(InterceptUnsubscribeMessage interceptUnsubscribeMessage) {
			status = Status.UNSUBSCRIBE;
		}
	}

	MQTTServer mqtt;

	@BeforeTest
	public void setUp() {
		mqtt = new MQTTServer();
		//TODO: Remove this when we test init and change the getinstance method
		mqtt.init("localhost", 1234);
	}

	@AfterTest
	public void tearDown() {
		mqtt = null;
		status = null;
	}

	@Test
	public void init() {
//		assertFalse(mqtt.isRunning());
		mqtt.init("localhost", 1234);
//		assertTrue(mqtt.isRunning());
	}

	@Test
	public void sendMessage() {
		Message message = new Message("Test message", "MQTT", null, "MQTT");
		mqtt.sendMessage(message);
	}

	@Test
	public void receiveMessage() {

	}

	private MQTTServer getInstance(){
		return mqtt;
	}
}

@@ -124,16 +124,131 @@
 ages.*;%0A
+import io.moquette.parser.proto.messages.AbstractMessage;%0Aimport io.moquette.parser.proto.messages.PublishMessage;%0A
 import n
@@ -470,17 +470,52 @@
 mockito.
-*
+Mockito;%0A%0Aimport java.nio.ByteBuffer
 ;%0A%0Aimpor
@@ -1896,16 +1896,51 @@
 age() %7B%0A
+%09%09MQTTServer mqtt = getInstance();%0A
 %09%09Messag
@@ -2008,132 +2008,732 @@
 ;%0A%09%09
-mqtt.sendMessage(message);%0A%09%7D%0A%0A%09@Test%0A%09public void receiveMessage() %7B%0A%0A%09%7D%0A%0A%09private MQTTServer getInstance()%7B%0A%09%09return mqtt;
+PublishMessage msg = createMQTTMessage();%0A%0A%09%09MQTTServer spy = Mockito.spy(mqtt);%0A%0A%09%09//Test that internalPublish is called with the correct parameter%0A%09%09Mockito.doReturn(msg).when(spy).createMQTTMessage(message);%0A%09%09spy.sendMessage(message);%0A%09%09Mockito.verify(spy, Mockito.atLeastOnce()).internalPublish(msg);%0A%09%7D%0A%0A%09@Test%0A%09public void receiveMessage() %7B%0A%0A%09%7D%0A%0A%09private MQTTServer getInstance()%7B%0A%09%09return mqtt;%0A%09%7D%0A%09private PublishMessage createMQTTMessage()%7B%0A%09%09PublishMessage msg = new PublishMessage();%0A%09%09ByteBuffer payload = ByteBuffer.wrap( %22This is a test%22.getBytes() );%0A%0A%09%09String topicName = %22Test%22;%0A%0A%09%09msg.setPayload( payload );%0A%09%09msg.setTopicName( topicName );%0A%09%09msg.setQos(AbstractMessage.QOSType.LEAST_ONE);%0A%09%09return msg;%0A
 %0A%09%7D%0A

Test for sendMessage and that it calls internalPublish