package com.eactive.eai.common.util;
 
import java.util.Iterator;
import java.util.Properties;

import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;

import com.eactive.eai.common.activemq.AmqQueueProducer;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.jms.JmsServiceLocator;
import com.eactive.eai.env.ElinkConfig;

public class JMSSender {
	static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);

	public static void sendToQueue(Object data, String connectionFactory, String destination, Properties prop)
			throws Exception {
		try {
			//내부에서 AmqPooledConnectionFactory 에서 uri 가져옴
			if (ElinkConfig.isUseInternalQueue()) {
				AmqQueueProducer aproducer = new AmqQueueProducer(null, destination);
				aproducer.sendMessage((java.io.Serializable) data, prop);
			} else {
				sendToJmsQueue(data, connectionFactory, destination, prop);
			}

		} catch (Exception e) {
			throw new Exception(ExceptionUtil.getErrorCode(e, "RECEAICUL001"));
		} finally {

		}
	}

	public static void sendToJmsQueue(Object data, String connectionFactory, String destination, Properties prop)
			throws JMSException {

		QueueConnectionFactory qconFactory = null;
		QueueConnection qcon = null;
		QueueSession qsession = null;
		Queue queue = null;
		QueueSender qsender = null;

		try {
			JmsServiceLocator locator = JmsServiceLocator.getInstance();

			qconFactory = locator.getQueueConnectionFactory(connectionFactory);
			if (qconFactory == null)
				throw new Exception("qconFactory not found -" + connectionFactory);
			qcon = qconFactory.createQueueConnection();
			if (qcon == null)
				throw new Exception("createQueueConnection return null");
			qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
			if (qsession == null)
				throw new Exception("createQueueSession return null");
			if (qconFactory == null)
				throw new Exception("qconFactory not found -" + connectionFactory);

			queue = locator.getQueue(destination);
			logger.info("resolved quene name is:" + "["+ queue + "]");
			qsender = qsession.createSender(queue);

			ObjectMessage msg = qsession.createObjectMessage();
			msg.setObject((java.io.Serializable) data);

			// Properties setting setStringProperties();
			if (prop != null) {
				Iterator it = prop.keySet().iterator();
				while (it.hasNext()) {
					String key = (String) it.next();
			        Object getObjectVal = prop.get(key);   // by jwhong 2025-09
			        String value = getObjectVal != null ? getObjectVal.toString() : "";  // by jwhong
			        msg.setStringProperty(key, value);
					//String value = prop.getProperty(key);
					//msg.setStringProperty(key, value);
				}
			}
			qsender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
			qsender.send(msg);
		} catch (Exception e) {
			logger.error("sendToJmsQueue error", e);
			// throw new JMSException("RECEAICUL001");
			throw new JMSException(ExceptionUtil.getErrorCode(e, "RECEAICUL001"));
		} finally {
			try {
				if (qsender != null)
					qsender.close();
			} catch (Exception e) {
			}
			try {
				if (qsession != null)
					qsession.close();
			} catch (Exception e) {
			}
			try {
				if (qcon != null)
					qcon.close();
			} catch (Exception e) {
			}
		}
	}

	public static void sendToTopic(Object data, String connectionFactory, String destination, Properties prop,
			String correlationID, long ttl) throws Exception {
		try {
			sendToJmsTopic(data, connectionFactory, destination, prop, correlationID, ttl);
		} catch (Exception e) {
			throw new Exception(ExceptionUtil.getErrorCode(e, "RECEAICUL002"));
		} finally {
			;
		}
	}

	public static void sendToJmsTopic(Object data, String connectionFactory, String destination, Properties prop,
			String correlationID, long ttl) throws JMSException {
		logger.warn("sendToJmsTopic-ST correlationID[" + correlationID + "]");
		TopicConnectionFactory topicFactory = null;
		TopicConnection tcon = null;
		TopicSession tsession = null;
		Topic topic = null;
		TopicPublisher publisher = null;
		int retryCount = 0;
		try {
			JmsServiceLocator locator = JmsServiceLocator.getInstance();
			topicFactory = locator.getTopicConnectionFactory(connectionFactory);
			if (topicFactory == null)
				throw new Exception("topicFactory not found - " + connectionFactory);
			// retry 3times
			while (retryCount < 3) {
				try {
					tcon = topicFactory.createTopicConnection();
				} catch (Exception ex) {
					retryCount++;
					if (retryCount < 3) {
//	    				if(logger.isWarn()) 
						logger.error("sendToJmsTopic correlationID[" + correlationID + "] retry count=" + retryCount);
						continue;
					}
					throw ex;
				}
				if (tcon != null)
					break;
			}

			tsession = tcon.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
			topic = locator.getTopic(destination);
			publisher = tsession.createPublisher(topic);
			// TTL Setting
			if (ttl > 0) {
				publisher.setTimeToLive(ttl);
			}

			ObjectMessage msg = tsession.createObjectMessage();
			msg.setObject((java.io.Serializable) data);
			if (correlationID != null) {
				msg.setJMSCorrelationID(correlationID);
			}
			if (prop != null) {
				Iterator it = prop.keySet().iterator();
				while (it.hasNext()) {
					String key = (String) it.next();
					String value = prop.getProperty(key);
					msg.setStringProperty(key, value);
				}
			}
			logger.info("publish factory =" + connectionFactory + ", destination=" + destination + ", correlationID="
					+ correlationID + ", ttl=" + ttl + ", message=" + msg);
			publisher.publish(msg, javax.jms.DeliveryMode.NON_PERSISTENT, javax.jms.Message.DEFAULT_DELIVERY_MODE, ttl);
			logger.warn("sendToJmsTopic-ED correlationID[" + correlationID + "]");
		} catch (Exception e) {
			logger.error("sendToJmsTopic] send error publish factory =" + connectionFactory + ", destination="
					+ destination + ", correlationID=" + correlationID + ", ttl=" + ttl + " " + e.getMessage(), e);
			throw new JMSException(ExceptionUtil.getErrorCode(e, "RECEAICUL002"));
		} finally {
			try {
				if (publisher != null)
					publisher.close();
			} catch (Exception e) {
			}
			try {
				if (tsession != null)
					tsession.close();
			} catch (Exception e) {
			}
			try {
				if (tcon != null)
					tcon.close();
			} catch (Exception e) {
			}
		}
		logger.warn("sendToJmsTopic-CL correlationID[" + correlationID + "]");
	}
}