package gov.va.med.esr;

import gov.va.med.esr.jms.vadir.inboundRequest.VadirServiceMilitaryHistoryRequest;
import gov.va.med.esr.jms.vadir.outboundResponse.VadirServiceResponseType;
import gov.va.med.esr.jms.vadir.outboundResponse.VadirServiceResponseWrapper;
import gov.va.med.esr.jms.vadir.outboundResponse.model.militaryHistory.MilitaryHistory;

import java.io.Serializable;

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

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

public class Go implements MessageListener {
	private static final Logger log = Logger.getLogger(Go.class);

	private JmsTemplate outboundJmsTemplate;
	private JmsTemplate inboundJmsTemplate;

	public static void main(String[] args) {
		try {
			ApplicationContext appContext = new ClassPathXmlApplicationContext(
					"/applicationContext.xml");
			Go client = (Go) appContext.getBean("go");

			// log.debug("Starting JMS listener...");
			// client.startListener();
			// sleep(2000);
			
			for (int count = 0; true; count++) {
				log.debug("Sending VADIR JMS request " + count + "...");
				client.simpleSend(count);
				log.debug("Sent.");
				sleep(10000);
			}
		} catch (Throwable t) {
			t.printStackTrace();
			sleep(5000);
		}
	}

	private static void sleep(long millis) {
		try {
			Thread.sleep(millis);
		} catch (InterruptedException ignored) {
		}
	}

	int count = 0;

	public void simpleSend(int count) {
		final VadirServiceMilitaryHistoryRequest request = new VadirServiceMilitaryHistoryRequest();
		request.setRequestId(290416);
		request.setPersonId(2220);
		request.setSsn("810907001");
		// request.setFirstName("LARRY");
		request.setLastName("JOHNSON");
		request.setDateOfBirth(java.sql.Date.valueOf("1952-03-10"));
		outboundJmsTemplate.send(new MessageCreator() {
			public Message createMessage(Session session) throws JMSException {
				return session.createObjectMessage(request);
			}
		});
	}

	public void onMessage(Message message) {
		if (message == null) {
			log.error("Received null message, ignoring...");
			return;
		}

		if (log.isDebugEnabled())
			log.debug("Received JMS response from EEService: " + message);

		if (message instanceof ObjectMessage == false) {
			log.error("Message must be of type " + ObjectMessage.class
					+ " but was actually a " + message.getClass());
			return;
		}

		ObjectMessage om = (ObjectMessage) message;

		Serializable o = null;
		try {
			o = om.getObject();
		} catch (JMSException e) {
			log.error("Unexpected exception while reading JMS message", e);
			return;
		}

		if (o instanceof VadirServiceResponseWrapper == false) {
			log.error("Message must contain a "
					+ VadirServiceResponseWrapper.class
					+ ", but instead contained a " + o.getClass());
			return;
		}

		VadirServiceResponseWrapper w = (VadirServiceResponseWrapper) o;
		long requestId = w.getRequestId();

		if (VadirServiceResponseType.isError(w.getResponseType())) {
			log.debug("Encountered error for request " + requestId + ": "
					+ w.getErrorMessage());
		} else if (w.getResponseType() == VadirServiceResponseType.NORMAL) {
			Serializable s = w.getResult();

			if (s instanceof MilitaryHistory == false) {
				log.error("Embedded result object for request " + requestId
						+ " was expected to be a " + MilitaryHistory.class
						+ " but was instead a " + s.getClass());
				return;
			}

			MilitaryHistory mh = (MilitaryHistory) s;
			log.info("Successful response for request "
					+ requestId
					+ ": "
					+ ToStringBuilder.reflectionToString(mh,
							ToStringStyle.MULTI_LINE_STYLE));
		}
	}

	public void startListener() {
		new Thread(new Runnable() {
			public void run() {
				while (true) {
					try {
						log.debug("Waiting for next message...");
						Message message = inboundJmsTemplate.receive();
						log.debug("Processing incoming message...");
						onMessage(message);
					} catch (Throwable t) {
						log.error("Error in listener:", t);
						sleep(5000);
					}
				}
			}
		}).start();
	}

	public void setOutboundJmsTemplate(JmsTemplate outboundJmsTemplate) {
		this.outboundJmsTemplate = outboundJmsTemplate;
	}

	public void setInboundJmsTemplate(JmsTemplate inboundJmsTemplate) {
		this.inboundJmsTemplate = inboundJmsTemplate;
	}
}
