package com.tandbergtv.ruleengine;

import java.util.Arrays;
import java.util.List;

import org.apache.log4j.Logger;

import com.tandbergtv.workflow.adaptor.AdaptorException;
import com.tandbergtv.workflow.adaptor.IAdaptor;
import com.tandbergtv.workflow.adaptor.IAdaptorRequest;
import com.tandbergtv.workflow.adaptor.IAdaptorResponse;
import com.tandbergtv.workflow.adaptor.conf.IAdaptorConfiguration;
import com.tandbergtv.workflow.comm.IDevice;
import com.tandbergtv.workflow.message.IMessageUID;
import com.tandbergtv.workflow.message.WorkflowMessage;
import com.tandbergtv.workflow.message.util.WPCLConverter;

/**
 * Custom Adaptor for Rule Engine device which sends/receive messages to/from JMS message queue It
 * also caches the rules device info on handling the first message so that it can be used for
 * generating asynchronous messages to workflow
 * 
 * @author Kinjal Mehta
 * 
 */
public class RuleEngineAdaptor implements IAdaptor {

	private static final String CREATE_PROCESS_UID = "re0101";

	private static final String RUN_NORMALIZATION_RULE_UID = "01re02";

	private static final String SEND_NORMALIZATION_PROGRESS_UID = "re0103";

	private static final List<String> messages = Arrays.asList(new String[] { CREATE_PROCESS_UID,
			RUN_NORMALIZATION_RULE_UID, SEND_NORMALIZATION_PROGRESS_UID });

	private Logger logger = Logger.getLogger(RuleEngineAdaptor.class);

	IAdaptorConfiguration conf = null;

	private IDevice rulesDevice = null;

	/**
	 * Inspects message UID of the message to detect if it can handle
	 */
	public boolean canDeliver(IAdaptorRequest arg0) {
		try {
			WPCLConverter converter = new WPCLConverter();
			WorkflowMessage wfsMessage = converter.convert(arg0.getMessage());
			if (messages.contains(wfsMessage.getMessageUID().getUID()))
				return true;
		} catch (Exception ex) {
			logger.warn("Unable to handle message " + arg0.getMessage().getPayload().getContent(),
					ex);
		}

		return false;
	}

	/**
	 * Binds to JMS queue during initializaion in order to listen for progress messages.
	 */
	public void init(IAdaptorConfiguration arg0) {
		conf = arg0;
		try {
			new NormalizationRulesResponseHandler(this, arg0);

		} catch (Exception e) {
			logger.error("Problem initialzing Rules Engine Adaptor", e);
		}

		logger.info("Initialized");

	}

	/**
	 * delegates message to right message handler
	 */
	public IAdaptorResponse transmit(IAdaptorRequest arg0) throws AdaptorException {

		IAdaptorResponse response = null;
		WorkflowMessage message = null;
		try {
			message = new WPCLConverter().convert(arg0.getMessage());
		} catch (Exception e) {
			throw new AdaptorException(e);
		}
		IMessageUID messageUID = message.getMessageUID();
		logger.debug("Processing message[" + messageUID.getUID() + "] - " + messageUID.getName());

		if (messageUID.getUID().equals(CREATE_PROCESS_UID))
			response = new CreateProcessHandler().handleMessage(message);
		else if (messageUID.getUID().equals(RUN_NORMALIZATION_RULE_UID)) {
			setRulesDevice(arg0);
			response = new RunNormalizationRuleHandler(conf).handleMessage(message);
		}

		return response;
	}

	public void destroy() {
		new NormalizationRulesResponseHandler().destroy();
		logger.info("Destroyed");
	}

	/**
	 * sets the rules destination from request so that it can be used to construct ansynchronous
	 * message
	 * 
	 * @param req
	 */
	private void setRulesDevice(IAdaptorRequest req) {
		IDevice destination = req.getDestinations().get(0);
		rulesDevice = destination;
	}

	public IDevice getRulesDevice() {
		return rulesDevice;
	}

}
