package com.eactive.eai.control;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueReceiver;
import javax.jms.QueueSession;
import javax.jms.TextMessage;

import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.jms.JmsServiceLocator;
import com.eactive.eai.common.util.Logger;

public class JMSQueueReceiver {
	static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
	private QueueConnectionFactory factory; 
	private QueueConnection con = null;
	private QueueSession ses = null;
	private Queue queue = null;
    private String jms_connectionfactory;
    private String queue_name;
    
    public java.io.Serializable receive(String queueConnectionFactory, String queueName, String traceNumber, int timeout) throws Exception {
        
        init(queueConnectionFactory, queueName);
        QueueReceiver receiver = null;
        
        try {
			if (con != null && ses != null) {
                
                if(traceNumber != null && traceNumber.length() > 0) {
                    receiver = ses.createReceiver(queue, "JMSCorrelationID = '" + traceNumber + "'");
                }
                else {
                    receiver = ses.createReceiver(queue);
                }
				Message message = (Message)receiver.receive(timeout);
                                
                if (message == null) {
                    String[] msgArgs = new String[2];
                    msgArgs[0] = queueName;
                    msgArgs[1] = traceNumber;
                    String rspErrorCode = "RECEAICJR001";            
                    String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs);            
                    throw new JMSQueueReceiverTimeOutException (rspErrorMsg);
                }
                
                if (message instanceof ObjectMessage) {
                	if(logger.isInfo()) logger.info("MESSAGE IS ObjectMessage");
                    return ((ObjectMessage)message).getObject();
                }                
                else if (message instanceof TextMessage) {
                	if(logger.isInfo()) logger.info("MESSAGE IS TextMessage");
                    return ((TextMessage)message).getText();
                }            
                else {
                    if(logger.isInfo()) logger.info("MESSAGE IS ELSEMESSAGE");
                    return "";
                }
			}
            else {
                throw new JMSException(new StringBuffer("연결되지 않음 TARGET >> localhost").append("에 대한 수신...").toString());
            }
		} catch (Exception e) {
			logger.error("receive error", e);
            throw e;
		} finally {
            if (receiver != null) try { receiver.close(); receiver = null; } catch (Throwable e) {
            	logger.error("receiver.close error", e);
            }
            close();
        }   
    }
      
    public void init(String queueConnectionFactory, String queueName) {
        jms_connectionfactory = queueConnectionFactory;
        queue_name = queueName;
        startQueueConnection();
    }
    
    public void close() {
       closeQueueConnection();    
    }
    
    private void startQueueConnection() {
        try {
        	JmsServiceLocator locator = JmsServiceLocator.getInstance();
			factory = locator.getQueueConnectionFactory(jms_connectionfactory);
			
			if(factory == null) {
				throw new Exception("QueueConnectionFactory is NULL - " + jms_connectionfactory);
			}
			con = factory.createQueueConnection();
			if(con == null) {
				throw new Exception("createQueueConnection is NULL - " + jms_connectionfactory);
			}
			ses = con.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
            queue = (Queue)locator.getQueue(queue_name);
			
			con.start();
		} catch (Throwable e) {
//            e.printStackTrace();
			logger.error("startQueueConnection error", e);
			closeQueueConnection();			
		}
    }
    private void closeQueueConnection() {
		if (ses != null) try { ses.close(); ses = null; } catch (Throwable e) {
			logger.error("ses.close error", e);
		}
		if (con != null) try { con.stop(); } catch (Throwable e) {
			logger.error("con.stop error", e);
		}
		if (con != null) try { con.close(); con = null; } catch (Throwable e) {
			logger.error("con.close error", e);
		}
    }
}
