package org.activemq;

import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;

import junit.framework.TestCase;

import org.activemq.broker.impl.BrokerContainerFactoryImpl;
import org.activemq.store.vm.VMPersistenceAdapter;
import org.activemq.store.vm.VMPersistenceAdapterFactory;

public class JmsDurableSubscriptionTest extends TestCase {
	
		
	public void testDurableTopic() throws Exception {
		Topics topics1 = new Topics("test", "id1");
		topics1.publish("message1");

		Topics topics2 = new Topics("test", "id3");
		assertReceiveEquals(topics2, null);

		topics2.publish("message2");
		assertReceiveEquals(topics2, "message2");
		assertReceiveEquals(topics2, null);

		topics1.close();
		topics2.close();
	}

	private void assertReceiveEquals(Topics topics3, String text) throws JMSException {
		
		TextMessage msg = (TextMessage)topics3.receive(1000);
		if( msg!=null )
			System.out.println("got: "+msg.getText());
		else 
			System.out.println("got: "+null);
		
		if( text==null ) {
			assertNull("Got:"+msg, msg);
		} else {
			assertEquals(text, msg.getText());
		}
	}

	static public class Topics {
        
		Connection connection;
		Session session;
		Destination destination;
		MessageConsumer consumer;
		MessageProducer producer;

		public Topics(String name) {
			this(name, String.valueOf(System.currentTimeMillis()));
		}

		public Topics(String name, String clientId) {
			try {
				System.setProperty("activemq.persistenceAdapterFactory", VMPersistenceAdapterFactory.class.getName());
				ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
						ActiveMQConnection.DEFAULT_USER,
						ActiveMQConnection.DEFAULT_PASSWORD,
						"peer://burgertime");
                
				connectionFactory
						.setBrokerContainerFactory(new BrokerContainerFactoryImpl(
								new VMPersistenceAdapter()));
				connectionFactory.setUseEmbeddedBroker(true);

				this.connection = connectionFactory.createTopicConnection();
				this.connection.setClientID(clientId);
				this.connection.start();

				this.session = connection.createSession(false,
						Session.AUTO_ACKNOWLEDGE);

				this.destination = this.session.createTopic(name);

				this.consumer = this.session.createDurableSubscriber(
						(Topic) destination, clientId);

				this.producer = this.session.createProducer(this.destination);
				this.producer.setDeliveryMode(DeliveryMode.PERSISTENT);
			} catch (JMSException e) {
				throw new RuntimeException(e);
			}
		}
		
		public Message receive(long timeout) throws JMSException {
			return consumer.receive(timeout);
		}

		public void publish(String message) {
			try {
				this.producer.send(this.session.createTextMessage(message));
			} catch (JMSException e) {
				throw new RuntimeException(e);
			}
		}

		public void close() {
			try {
				this.consumer.close();
				this.producer.close();
				this.session.close();
				this.connection.close();
			} catch (JMSException e) {
				throw new RuntimeException(e);
			}
		}
	}
}