package eu.dnetlib.enabling.is.sn;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.util.Queue;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;

import eu.dnetlib.enabling.is.sn.NotificationInvocationLogger.Entry;
import eu.dnetlib.enabling.is.sn.NotificationInvocationLogger.Entry.Status;

/**
 * Memory notification logger test.
 *
 * @author marko
 *
 */
public class MemoryNotificationInvocationLoggerTest {

	/**
	 * some size.
	 */
	private static final int SOME_SIZE = 300;

	/**
	 * instance under test.
	 */
	private transient MemoryNotificationInvocationLogger logger;

	/**
	 * message bock.
	 */
	@Mock
	private transient NotificationMessage message;

	/**
	 * common setup.
	 *
	 * @throws Exception
	 *             happens
	 */
	@Before
	public void setUp() throws Exception {
		logger = new MemoryNotificationInvocationLogger();
	}

	/**
	 * test logging and queue management.
	 */
	@Test
	public void testStartLogging() {
		final Queue<NotificationInvocationLogger.Entry> queue = logger.getQueue();

		assertEquals("queue", 0, queue.size());

		final NotificationInvocationLogger.Entry entry = logger.startLogging(null, message);

		assertNotNull("got an entry", entry);
		assertEquals("queue", 1, queue.size());

		for (int i = 0; i < SOME_SIZE; i++)
			logger.startLogging(null, message);
		assertEquals("queue", logger.getSize(), queue.size());
	}

	/**
	 * test success.
	 */
	@Test
	public void testSuccess() {
		final NotificationInvocationLogger.Entry entry = logger.startLogging(null, message);
		entry.success();

		final Queue<NotificationInvocationLogger.Entry> queue = logger.getQueue();
		final Entry entry2 = queue.remove();
		assertEquals("success", Status.Succeeded, entry2.getStatus());
	}

	/**
	 * test failure.
	 */
	@Test
	public void testFailure() {
		final NotificationInvocationLogger.Entry entry = logger.startLogging(null, message);
		entry.failure(new IllegalStateException("dummy"));

		final Queue<NotificationInvocationLogger.Entry> queue = logger.getQueue();
		final Entry entry2 = queue.remove();
		assertEquals("failure", Status.Failed, entry2.getStatus());

		assertTrue("exception", entry2.getException() instanceof IllegalStateException);
	}

	/**
	 * test ongoing.
	 */
	@Test
	public void testOngoing() {
		logger.startLogging(null, message);

		final Queue<NotificationInvocationLogger.Entry> queue = logger.getQueue();
		final Entry entry2 = queue.remove();

		assertEquals("queued", Status.Queued, entry2.getStatus());
		entry2.ongoing();
		assertEquals("ongoing", Status.Ongoing, entry2.getStatus());
	}


}
