package com.eactive.eai.flowcontrol.websphere;

import com.eactive.eai.common.message.EAIMessage;
import com.eactive.eai.common.routing.ElinkESBProcessProxy;
import com.eactive.eai.common.routing.RoutingManager;
import com.eactive.eai.common.routing.RoutingVO;
import com.eactive.eai.common.util.Logger;

import javax.jms.*;
import java.util.Enumeration;
import java.util.Properties;
import java.lang.IllegalStateException;

public class DefaultQueueConsumer  implements Runnable, ExceptionListener {
	
	private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
	
	Connection connection = null;
	Session session = null;
	MessageConsumer consumer = null;
	String name = null;
	String queue = null;
	boolean run = true;
	
	public DefaultQueueConsumer(String name, Connection con, String queue) {
		this.connection = con;
		 try {
			 this.name = name;
			 this.queue = queue;
			connection.start();
			connection.setExceptionListener(this);

	        // Create a Session
	        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

	         // Create the destination (Topic or Queue)
	        Destination destination = session.createQueue(queue);
	        consumer = session.createConsumer(destination); 
		} catch (JMSException e) {
			logger.error(e);
		}
	}
	
	@Override
	public void run() {
		EAIMessage eaiMessage = null;
		while(run) {
			try {
				 Message message = consumer.receive(2000);
	             
				 ObjectMessage omsg = null;
				 
				 if(message == null) {
//					 logger.warn(name + " -> EMPTY MESSAGE...");
					 continue;
				 }
				 
				 if(message instanceof ObjectMessage) {
		            omsg = (ObjectMessage)message;
		        } else {
		        	throw new RuntimeException(name+" Invlid JMS Message Type. - "+message);
		        }
			 	
				 try {
		            eaiMessage = (EAIMessage)omsg.getObject();
		        } catch(Exception e) {
		            throw new RuntimeException(name+" Invlid value object in ObjectMessage. - "+e.getMessage() );
		        }
				 
//				 String guidLogPrefix = "GUID["+eaiMessage.getKbMsg().getKBHeader().getGuIdNo()+"] UUID["+eaiMessage.getSvcOgNo()+"] ";
				 String guidLogPrefix = "GUID["+ eaiMessage.getMapper().getGuid(eaiMessage.getStandardMessage()) +"] UUID["+eaiMessage.getSvcOgNo()+"] ";
				 
	 	        RoutingVO routingVO = RoutingManager.getInstance().getRoutingVO(eaiMessage.getFlwCntlRtnNm());
	 	        String serviceURI = routingVO.getSyncRoutingPath();
	 	        boolean isLocal = true;
	 	
	 	       Properties prop = new Properties();
		        try {
		            Enumeration en = omsg.getPropertyNames();
		            for (; en.hasMoreElements(); ) {
		                String propName = (String)en.nextElement();
		                String propValue = omsg.getStringProperty(propName);
		                prop.setProperty(propName, propValue);
		            }
		        } catch(JMSException e) {
		        	throw new RuntimeException(name+" onMessage Error. - "+e.getMessage());		            
		        }
		        
		        try {
		        	 if(logger.isInfo()) logger.info("Websphere JMS Receiver :  " + guidLogPrefix + eaiMessage);
		            eaiMessage = ElinkESBProcessProxy.callElinkESBProcess(serviceURI, eaiMessage, isLocal, prop);
		        } catch(Exception e) {
		        	throw new RuntimeException("Websphere JMS Receiver :  " + guidLogPrefix +name+" onMessage Error. - "+e.getMessage());
		        } 
			} 
			catch(IllegalStateException ise) {
				logger.error(name+" IllegalStateException = " + ise.getMessage(), ise);
				
			}
			catch(JMSException e) {        	
				logger.error(name+" JMSException = " + e.getMessage(), e);
				run = false;
	    	}
			catch(RuntimeException e) {        	
				logger.error(name+" RuntimeException = " + e.getMessage(), e);
	    	}
		}		
	}
	
	public void stop() {
		run = false;
        if(consumer != null)
				try {
					consumer.close();
				} catch (JMSException e) { }
    	if(session != null)
				try {
					session.close();
				} catch (JMSException e) { }
    	if(connection != null)
				try {
					connection.close();
				} catch (JMSException e) { }
	}
	
	@Override
	public void onException(JMSException arg0) {
		 logger.error("JMS Exception occured.  Shutting down client.");
		 stop();
	}
}
