package com.eactive.eai.agent.jms;

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;

import javax.jms.Message;
import javax.jms.ObjectMessage;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueReceiver;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.naming.InitialContext;

import com.eactive.eai.agent.command.Command;
import com.eactive.eai.agent.command.CommandException;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.logger.EAILogSender;
import com.eactive.eai.common.message.EAIMessage;
import com.eactive.eai.common.util.Logger;

public class RemoveMessageCommand extends Command {
	private static final long serialVersionUID = 1L;
	public final static String JMS_FACTORY = "com.eactive.eai.common.FlowRouterConnectionFactory";

	public RemoveMessageCommand() {
		super("RemoveMessageCommand");
	}

	public Object execute() throws CommandException {
		Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
		if (logger.isInfo())
			logger.info(this.name + " is executed");

		if (!(args instanceof HashMap)) {
			throw new CommandException("Invalid Args - " + args);
		}

		try {
			HashMap map = (HashMap) args;
			String queueName = (String) map.get("queueName");
			String eaiSvcCd = (String) map.get("eaiSvcCd"); // EAISVCCD
			String selector = "";

			if (eaiSvcCd != null && eaiSvcCd.length() > 0) {
				selector = "EAISVCCD='" + eaiSvcCd + "'";
			}

			purgeQueue(queueName, selector, true);

		} catch (Exception e) {
			if (logger.isError())
				logger.error("execute", e);
			throw new CommandException(e.getMessage());
		}
		return "success";
	}

	public static int purgeQueue(String queueName, String mSelector, boolean isLogging) throws Exception {
		Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
		int count = 0;
		InitialContext ctx = new InitialContext();

		long sTime = System.currentTimeMillis();
		long cTime = 0;
		int purgeCount = 0;

		try {
			DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yy/MM/dd kk:mm:ss");

			QueueConnectionFactory qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY);
			try (QueueConnection qcon = qconFactory.createQueueConnection();
					QueueSession qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
					QueueReceiver qreceiver = createQueueReceiver(qsession, queueName, ctx, mSelector)) {
				qcon.start();

				logger.warn("RemoveMessageCommand]  " + queueName + " - Queued JMS Messages: "
						+ DATE_FORMAT.format(ZonedDateTime.now()));
				cTime = System.currentTimeMillis() - sTime;
				sTime = System.currentTimeMillis();

				Message m = null;
				while ((m = qreceiver.receiveNoWait()) != null) {
					purgeCount++;

					if (isLogging && m instanceof ObjectMessage) {
						processObjectMessage((ObjectMessage) m);
						count++;
					}
				}

				if (logger.isWarn()) {
					logger.warn("RemoveMessageCommand] Purge " + purgeCount + " messages completed : connect time("
							+ cTime + ") ms, purge time (" + (System.currentTimeMillis() - sTime) + ") ms");
				}

				return count;
			}
		} catch (Exception e) {
			throw e;
		}
	}

	private static QueueReceiver createQueueReceiver(QueueSession qsession, String queueName, InitialContext ctx,
			String mSelector) throws Exception {
		javax.jms.Queue queue = (javax.jms.Queue) ctx.lookup(queueName);
		return (mSelector != null && mSelector.length() > 0) ? qsession.createReceiver(queue, mSelector)
				: qsession.createReceiver(queue);
	}

	private static void processObjectMessage(ObjectMessage objMessage) {
		try {
			EAIMessage eaiMsg = (EAIMessage) objMessage.getObject();
			String rspErrorCode = "RECEAIFQR100"; // 운영자에 의해 큐에서 삭제됨
			String rspErrorMsg = ExceptionUtil.make(rspErrorCode, "");
//			eaiMsg.setRspErrCd(rspErrorCode);
//			eaiMsg.setRspErrMsg(rspErrorMsg);
			eaiMsg.setRspErr(rspErrorCode,rspErrorMsg);
			eaiMsg.setLogPssSno(eaiMsg.getLogPssSno() + 100);
			EAILogSender.send(eaiMsg, null);
		} catch (Exception e) {
			Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
			if (logger.isError()) {
				logger.error("RemoveMessageCommand] DB Log 실패 - " + e.getMessage());
			}
		}
	}
}
