package at.ac.tuwien.sbc.valesriegler.waiter.jms.messageListeners;

import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import at.ac.tuwien.sbc.valesriegler.common.Util;
import at.ac.tuwien.sbc.valesriegler.group.actions.TableRequest;
import at.ac.tuwien.sbc.valesriegler.group.actions.TableResponse;
import at.ac.tuwien.sbc.valesriegler.types.Table;
import at.ac.tuwien.sbc.valesriegler.waiter.jms.JMSWaiter;

/**
 * Listener listening on the WantToSitAtTable MQ, handling all incomming
 * messages.
 * 
 * @author jan
 * 
 */
public class WantToSitAtTable implements MessageListener {
	private static final Logger log = LoggerFactory.getLogger(WantToSitAtTable.class);
	private final JMSWaiter waiter;

	public WantToSitAtTable(JMSWaiter waiter) {
		this.waiter = waiter;
	}

	@Override
	public void onMessage(Message msg) {
		try {
			msg.acknowledge();
			if (msg instanceof ObjectMessage) {
				ObjectMessage objMsg = (ObjectMessage) msg;
				Object obj = objMsg.getObject();

				if (obj instanceof TableRequest) {
					TableRequest tablerequest = (TableRequest) obj;
					log.debug("Received: " + tablerequest);

					// generate random delay
					if (!Util.runSimulation) {
						Thread.sleep((long) (Math.random() * 10000));
					}

					ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(waiter.getCONNECTSTRING());
					Connection connection = connectionFactory.createConnection();
					connection.start();
					Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

					MessageConsumer consumer = session.createConsumer(session.createQueue("TablesFree"));
					Message trm = consumer.receive();
					if (trm instanceof ObjectMessage) {
						ObjectMessage tom = (ObjectMessage) trm;
						Object tabledata = tom.getObject();

						if (tabledata instanceof Table) {
							session.close();
							Table table = (Table) tabledata;
							System.out.println("Received: " + table);
							synchronized (waiter) {
								TableResponse tr = new TableResponse(tablerequest.getGroupdata(), table, waiter.getId());
								session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
								MessageProducer ret = session.createProducer(session.createQueue("GroupConnector"));
								ret.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
								ret.send(session.createObjectMessage(tr));

								MessageProducer informPizzariaGui = session.createProducer(session.createQueue("PizzeriaConnector"));
								informPizzariaGui.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
								informPizzariaGui.send(session.createObjectMessage(tr));
								session.close();
							}
						} else {
							log.warn("Received unknown Object: " + tabledata);
						}
					} else {
						log.warn("Received unknown Message: " + trm);
					}
					session.close();
					connection.close();
				} else {
					log.warn("Received unknown Object: " + obj);
				}
			} else {
				log.warn("Received unknown Message: " + msg);
			}
		} catch (JMSException e) {
			log.error("EXCEPTION!", e);
		} catch (InterruptedException e) {
			log.error("EXCEPTION!", e);
		}
	}

}
