package com.tandbergtv.watchpoint.pmm.util;

import java.util.ArrayList;
import java.util.List;

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.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.apache.log4j.Logger;

import com.tandbergtv.cms.rules.service.category.IRuleExecutionHandler;
import com.tandbergtv.marvin.udt.ActionMessage;
import com.tandbergtv.marvin.udt.RuleResults;
import com.tandbergtv.marvin.udt.TreEvent;
import com.tandbergtv.marvin.udt.TreEventType;
import com.tandbergtv.marvin.udt.TrePackage;
import com.tandbergtv.marvin.udt.ValidationMessage;
import com.tandbergtv.watchpoint.pmm.entities.Title;

public class RulesEngineFacade {
	private static final Logger logger = Logger.getLogger(RulesEngineFacade.class);
	
	public static Title nationalize(Title title, String event) {
		return nationalize(title, TreEventType.lookup(event));
	}
	
	public static Title nationalize(Title title, TreEventType event) {
		
		TrePackage tp = new TrePackage();
		tp.setName(TrePackage.NORMALIZATION);
		
		TreEvent te = new TreEvent();
		te.setType(event);
		
		RuleResults ruleResults = getRuleExecutionHandler().runRuler(title, te, tp);

		if(ruleResults != null)
			return ruleResults.getTitle();
		
		//when there are no rules, rulesEngine does not return any results
		return title;
	}
	
	public static List<ValidationMessage> validate(Title title) {
		List<ValidationMessage> validationMessages = new ArrayList<ValidationMessage>();
		IRuleExecutionHandler reh = getRuleExecutionHandler();
		List<Title> titles = new ArrayList<Title>();
		titles.add(title);
		RuleResults ruleResults = reh.runValidateRuler(title);

		//get validation messages from ruleResults list
		if(ruleResults != null)
			for(ActionMessage message : ruleResults.getMessages())
				validationMessages.add((ValidationMessage) message);
		
		return validationMessages;
	}
	
	public static void sendUICreatedEvent(Long titleId) {
		sendEvent(TreEventType.TITLEUICREATE, titleId);
	}

	public static void sendUIUpdatedEvent(Long titleId) {
		sendEvent(TreEventType.TITLEUIUPDATE, titleId);
	}

	public static void sendNationalizedEvent(Long titleId) {
		sendEvent(TreEventType.TITLENATIONALIZED, titleId);
	}

	public static void sendIngestedEvent(Long titleId) {
		sendEvent(TreEventType.INGEST, titleId);
	}

	private static IRuleExecutionHandler getRuleExecutionHandler() {
		IRuleExecutionHandler reh = null;
		try {
			reh = (IRuleExecutionHandler) new InitialContext().lookup("cms/EventHandler/local");
		} catch (NamingException e) {
			logger.error("Unable to obtain IRuleExecutionHandler implementation from context", e);
		}
		return reh;
	}
	
	private static void sendEvent(TreEventType eventType, Long titleId) {
		Context context = null;
		QueueConnection queueConnection = null;
		QueueSession queueSession = null;
		Queue queue = null;
		QueueSender queueSender = null;
		
		try {
			context = new InitialContext();
			QueueConnectionFactory queueFactory = (QueueConnectionFactory) context.lookup("java:/JmsXA");
			queueConnection = queueFactory.createQueueConnection();
			queueSession = queueConnection.createQueueSession(true, 0);
			queue = (Queue) context.lookup("queue/EventQueue");
			queueSender = queueSession.createSender(queue);

			ObjectMessage message = queueSession.createObjectMessage();
			message.setStringProperty("eventType", eventType.getKey());
			message.setLongProperty("titleId", titleId);
			
			queueSender.send(queue, message);
		} catch (Exception e) {
			logger.error("Exception while sending the event", e);
		} finally {
				try {
					if(queueSession != null)
						queueSession.close();
					if(context != null)
						context.close();
				} catch (Exception e) {
					logger.error("Failed to close the JMS session and context", e);
				}
		}
	}
}
