/**
 * RuleHandlerClassFinder.java
 * Created on May 20, 2008
 * (C) Copyright TANDBERG Television Ltd.
 */
package com.tandbergtv.watchpoint.pmm.job.util;

import java.util.List;

import org.apache.log4j.Logger;

import com.tandbergtv.watchpoint.pmm.entities.EntityType;
import com.tandbergtv.watchpoint.pmm.entities.RuleParameter;
import com.tandbergtv.watchpoint.pmm.entities.RuleParameterDataType;
import com.tandbergtv.watchpoint.pmm.entities.RuleTypeParameter;
import com.tandbergtv.watchpoint.pmm.job.conf.ParameterReferenceFileParser;

/**
 * This class is a helper class used to determine the callback class for the selected rule
 * 
 * @author spuranik
 */
public class RuleCallbackClassFinder {

	private static String DEFAULT_CALLBACK_CLASS = "com.tandbergtv.watchpoint.pmm.job.callback.DefaultCallback";
	private static final Logger logger = Logger.getLogger(RuleCallbackClassFinder.class);

	/**
	 * @param isAssociatedWithTitles
	 * 		whether or not the rule for which the callback is being requested 
	 * 		is associated with titles or not. 
	 * @param type
	 * 		entitytype which will be searched for the parameter to get the callback
	 * @param ruleParams
	 * 		list of parameters entered by the user
	 * @param ruleTypeParams
	 * 		list of rule type parameters. Will be used to check if there is 
	 * 		a PARAMETERREF type
	 * @return
	 * 		fully qualified name of the callback class for the selected parameter 
	 * 		ref (if any) or the default if not associated with titles.
	 */
	public String getCallbackClass(boolean isAssociatedWithTitles,
			EntityType type, List<RuleParameter> ruleParams,
			List<RuleTypeParameter> ruleTypeParams, String spec) {
		try {
			// if the rule (via the job) is not associated with titles, return 
			// the default callback which kicks off a single work order.
			if (!isAssociatedWithTitles)
				return DEFAULT_CALLBACK_CLASS;

			// if not then check if the ruletype params has any PARAMETERREF type
			// and use the value of the corresponding order in the ruleParams to 
			// get the callback from ParameterReferenceHelper which has a list of
			// entity types and menu items along with the callback info.
			int order = getParameterRefOrder(ruleTypeParams);
			if (order != -1) {
				RuleParameter ruleParameter = getRuleParameter(ruleParams, order);
				String groupName = ParameterReferenceHelper.getGroupName(ruleParameter.getValue());
				String parentGroup = ParameterReferenceHelper.getParentGroup(groupName);
				
				ParameterReferenceFileParser helper = new ParameterReferenceFileParser(spec);
				return helper.getCallback(type, parentGroup);
			}
		} catch (Exception e) {
			logger.error("Error while getting callback class for type: " + type + e.toString());
		}

		// if no callback is found return an empty string
		return new String();
	}

	/**
	 * @param ruleTypeParams
	 * 		checks if any of the params are of PARAMETERREF
	 * 		NOTE: the first matching one is sent. Multiple PARAMETER refs
	 * 		are not supported. This is the case everywhere.    
	 * @return
	 * 		the order of the parameter whose datatype = PARAMETERREF
	 */
	private int getParameterRefOrder(List<RuleTypeParameter> ruleTypeParams) {
		for (RuleTypeParameter parameter : ruleTypeParams) {
			if (parameter.getType() == RuleParameterDataType.PARAMETERREF) {
				return parameter.getOrder();
			}
		}
		return -1;
	}

	/**
	 * @param ruleParams
	 * 		list of rule params from which the rule param for the 
	 * 		given order is requested
	 * @param order
	 * 		the order of the requested rule parameter
	 * @return
	 * 		the rule parameter object whose order matches the given order.
	 */
	private RuleParameter getRuleParameter(List<RuleParameter> ruleParams, int order) {
		for (RuleParameter param : ruleParams) {
			if (param.getOrder() == order)
				return param;
		}
		return null;
	}

}
