/*
 * Copyright (C) 2014 see CREDITS.txt
 * All rights reserved.
 */

package fi.uef.envi.wavellite.component.writer.activemq;

import java.io.Serializable;
import java.util.Properties;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;

import fi.uef.envi.wavellite.component.activemq.ActiveMqConnection;
import fi.uef.envi.wavellite.component.activemq.ActiveMqOptions;
import fi.uef.envi.wavellite.component.writer.base.AbstractWriterSituation;
import fi.uef.envi.wavellite.entity.situation.Situation;
import fi.uef.envi.wavellite.module.store.ModuleStore;

/**
 * <p>
 * Title: WriterSituationActiveMq
 * </p>
 * <p>
 * Description:
 * </p>
 * <p>
 * Project: Wavellite Component
 * </p>
 * <p>
 * Copyright: Copyright (C) 2014
 * </p>
 * 
 * @author Markus Stocker
 */

public class WriterSituationActiveMq extends AbstractWriterSituation
		implements MessageListener {

	private ModuleStore store;
	private MessageConsumer consumer;
	private String consumerDestinationName;
	private ActiveMqConnection connection;

	public WriterSituationActiveMq(ModuleStore store,
			String consumerDestinationName) {
		this(store, consumerDestinationName,
				ActiveMqOptions.connectionFactoryName);
	}
	
	public WriterSituationActiveMq(ModuleStore store,
			String consumerDestinationName, Properties properties) {
		this(store, consumerDestinationName,
				ActiveMqOptions.connectionFactoryName, properties);
	}

	public WriterSituationActiveMq(ModuleStore store,
			String consumerDestinationName, String connectionFactoryName) {
		this(store, consumerDestinationName, connectionFactoryName, null);
	}
	
	public WriterSituationActiveMq(ModuleStore store,
			String consumerDestinationName, String connectionFactoryName, Properties properties) {
		if (store == null)
			throw new NullPointerException("[store = null]");
		if (consumerDestinationName == null)
			throw new NullPointerException("[destinationName = null]");
		if (connectionFactoryName == null)
			throw new NullPointerException("[connectionFactoryName = null]");

		this.store = store;
		this.consumerDestinationName = consumerDestinationName;
		this.connection = new ActiveMqConnection(connectionFactoryName, properties);
		this.open();
	}

	@Override
	public void execute(Situation entity) {
		store.consider(entity);
	}

	@Override
	public void open() {
		try {
			consumer = connection.getConsumer(consumerDestinationName);
			consumer.setMessageListener(this);
		} catch (JMSException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void close() {
		connection.close();
	}

	@Override
	public void onMessage(Message message) {
		if (!(message instanceof ObjectMessage))
			throw new RuntimeException(this.getClass().getName()
					+ " expects message to be a ObjectMessage but is "
					+ message.getClass().getName());

		ObjectMessage m = (ObjectMessage) message;

		try {
			Serializable r = m.getObject();

			if (!(r instanceof Situation))
				throw new RuntimeException(
						this.getClass().getName()
								+ " expects the message object to be a Situation but is "
								+ m.getClass().getName());

			execute((Situation) r);
		} catch (JMSException e) {
			throw new RuntimeException(e);
		}
	}

}
