/**
 * JobManagementAction.java
 * Created on May 16, 2008
 * (C) Copyright TANDBERG Television Ltd.
 */
package com.tandbergtv.watchpoint.pmm.web.actions.job;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;

import com.tandbergtv.watchpoint.pmm.entities.ContainerType;
import com.tandbergtv.watchpoint.pmm.entities.EntityType;
import com.tandbergtv.watchpoint.pmm.entities.IContainer;
import com.tandbergtv.watchpoint.pmm.entities.Job;
import com.tandbergtv.watchpoint.pmm.entities.JobParameter;
import com.tandbergtv.watchpoint.pmm.entities.Partner;
import com.tandbergtv.watchpoint.pmm.entities.PartnerType;
import com.tandbergtv.watchpoint.pmm.entities.Rule;
import com.tandbergtv.watchpoint.pmm.entities.RuleParameter;
import com.tandbergtv.watchpoint.pmm.entities.RuleParameterDataType;
import com.tandbergtv.watchpoint.pmm.entities.RuleType;
import com.tandbergtv.watchpoint.pmm.entities.RuleTypeParameter;
import com.tandbergtv.watchpoint.pmm.job.IJobManager;
import com.tandbergtv.watchpoint.pmm.job.JobManager;
import com.tandbergtv.watchpoint.pmm.job.conf.RuleTypeInfoLoader;
import com.tandbergtv.watchpoint.pmm.job.ui.JobUIConstants;
import com.tandbergtv.watchpoint.pmm.job.util.RuleCallbackClassFinder;
import com.tandbergtv.watchpoint.pmm.util.ContextManager;
import com.tandbergtv.watchpoint.pmm.util.IContextManager;
import com.tandbergtv.watchpoint.pmm.web.formbeans.job.JobForm;
import com.tandbergtv.watchpoint.pmm.web.formbeans.job.JobParameterForm;
import com.tandbergtv.watchpoint.pmm.web.formbeans.job.RuleParameterForm;
import com.tandbergtv.watchpoint.pmm.web.util.JobFormPopulator;
import com.tandbergtv.watchpoint.pmm.web.validators.JobValidator;
import com.tandbergtv.workflow.core.ProcessPriority;
import com.tandbergtv.workflow.core.TaskVariable;
import com.tandbergtv.workflow.core.service.ServiceRegistry;
import com.tandbergtv.workflow.core.service.cache.ICacheService;

/**
 * This action class handles all messages when creating/updating a job
 * 
 * @author spuranik
 */
public class JobManagementAction extends DispatchAction {

	private Logger logger = Logger.getLogger(JobManagementAction.class);
	private static String CREATEJOB = "createJob";
	private static String POST_CREATE_UPDATE = "postCreateUpdate";
	private static String CONTAINER_CACHE_SERVICE_NAME = "Container Cache";
	private static String PARAMETER_NAME_DELIMETER = ",";
	private static final String DATE_FORMAT = "yyyy-MM-dd";
	private static int INVALID_INDEX = -1;
	private static String SPACE = " ";
	private static String DEFAULT_TIME = "12:00 am";

	/**
	 * This method is called when the user wants to create a job and the page needs to display all
	 * the elements
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public ActionForward showJobPage(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception {

		JobForm jobform = (JobForm) form;

		long contextId = jobform.getContextId();
		logger.debug("ContextId: " + contextId);

		ICacheService<IContainer> containerCache = (ICacheService<IContainer>) ServiceRegistry
				.getDefault().lookup(CONTAINER_CACHE_SERVICE_NAME);
		IContainer container = containerCache.get(contextId);
		// id is not yet available
		// contextId is already set

		// set container type and name for the label
		jobform.setEntityName(container.getContainerName());
		ContainerType containerType = container.getContainerType();
		if (containerType == ContainerType.PARTNER) {
			PartnerType partnerType = ((Partner) container).getType();
			if (partnerType == PartnerType.SELF) {
				jobform.setEntityType(partnerType.toString());
			} else
				jobform.setEntityType(container.getContainerType().toString());
		} else {
			jobform.setEntityType(container.getContainerType().toString());
		}

		// set whether or not titles are Associated, by default yes
		jobform.setIsAssociatedWithTitles("true");

		JobFormPopulator.setRequiredInfoInForm(jobform);

		setSelectedRuleTypeToDefault(jobform);
		
		return mapping.findForward(CREATEJOB);
	}

	/**
	 * This method is called to retrieve the variables for a selected template that the user chose
	 * when creating a job.
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ActionForward getTemplateParameters(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception {

		JobForm jobform = (JobForm) form;

		// set the job parameters
		String templateName = jobform.getSelectedTemplate();
		Collection<TaskVariable> variables = JobFormPopulator.getTemplateParameters(templateName);
		// set these names in jobParamNames
		setJobParamNames(variables, jobform);
		List<JobParameterForm> jobParameters = JobFormPopulator.prepareJobParameterForm(variables,
				null);
		jobform.setParams(jobParameters);
		jobform.setValue(null);

		JobFormPopulator.setRequiredInfoInForm(jobform);

		return mapping.findForward(CREATEJOB);
	}

	/**
	 * This method is called when the user selects the radio button used to associate/dis-associate
	 * the schedule rule with titles.
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ActionForward getScheduleRulesAndMenu(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception {

		JobForm jobform = (JobForm) form;

		// no need to remember the job param values and the rule params
		jobform.setRuleParamValue(null);
		jobform.setValue(null);
		
		// clear the start and end dates if set
		jobform.setJobStartDate("");
		jobform.setJobEndDate("");

		JobFormPopulator.setRequiredInfoInForm(jobform);
		
		setSelectedRuleTypeToDefault(jobform);
		
		return mapping.findForward(CREATEJOB);
	}

	/**
	 * This method is called when the user wants to update an existing job.
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ActionForward getJob(ActionMapping mapping, ActionForm form, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		JobForm jobform = (JobForm) form;

		// get the job from db
		// populate the form fields and return

		IJobManager jobMgr = JobManager.getInstance();
		Job job = jobMgr.getJob(jobform.getId());

		jobform.setId(job.getId());
		jobform.setContextId(job.getContext().getId());
		// set the right partner type
		ContainerType type = job.getContext().getContainerType();
		if (type == ContainerType.PARTNER) {
			PartnerType pType = ((Partner) job.getContext().getContainer()).getType();
			if (pType == PartnerType.SELF) {
				jobform.setEntityType(PartnerType.SELF.toString());
			} else {
				jobform.setEntityType(job.getContext().getContainerType().toString());
			}
		} else {
			jobform.setEntityType(job.getContext().getContainerType().toString());
		}
		jobform.setEntityName(job.getContext().getContainer().getContainerName());
		jobform.setName(job.getName());
		jobform.setIsAssociatedWithTitles(Boolean.toString(job.getRule().getType()
				.getTitlesAssociated()));

		// set the start date
		String jobRuleTypeName = job.getRule().getType().getName();
		// Don't like to do this! Set the start date only if it makes sense for this rule.		
		if (JobValidator.startDateAllowed(jobRuleTypeName)) {
			String[] start = job.getRule().getStartDate().toString().split(SPACE);
			jobform.setJobStartDate(start[0]);
			
			// use the current date or else, quartz will send misfires when this job is rescheduled!
			if (JobValidator.isDateInPast(start[0], DATE_FORMAT)) {			
					Calendar cal = Calendar.getInstance();
					Date today = cal.getTime();
					SimpleDateFormat fmt = new SimpleDateFormat(DATE_FORMAT);
					String todayStr = fmt.format(today);
					jobform.setJobStartDate(todayStr);
			}			
		}

		// set the end date only if it makes sense as per the rule.
		if (JobValidator.endDateAllowed(jobRuleTypeName)) {
			if (job.getRule().getEndDate() != null) {
				String[] end = job.getRule().getEndDate().toString().split(
						SPACE);
				jobform.setJobEndDate(end[0]);
			}
		}

		jobform.setSelectedPriority(job.getPriority().toString());

		jobform.setSelectedTemplate(job.getTemplateName());
		setJobParameterValueInfo(job, jobform);

		JobFormPopulator.setRequiredInfoInForm(jobform);

		// doing this after filling the required fields because we don't have ruleparametervalues
		// for all rule types
		jobform.setSelectedRuleType(job.getRule().getType().getName());
		setJobRuleValueInfo(job, jobform);

		return mapping.findForward(CREATEJOB);
	}

	/**
	 * This method is called when the user has filled in the job creation UI and clicked on 'save'
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ActionForward createJob(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception {

		JobForm jobform = (JobForm) form;

		// prepare the job object from the form and send it to the job manager
		IJobManager jobMgr = JobManager.getInstance();
		IContextManager ctxMgr = ContextManager.getInstance();

		Job job = new Job();
		job.setName(jobform.getName());
		job.setContext(ctxMgr.getContext(jobform.getContextId()));
		job.setPriority(ProcessPriority.valueOf(jobform.getSelectedPriority()));
		job.setTemplateName(jobform.getSelectedTemplate());
		job.setJobParams(createJobParameters(job, jobform.getJobParamNames(), jobform.getValue()));
		job.setRule(createRule(jobform));

		if (jobMgr.createJob(job)) {
			jobform.setId(job.getId());
			request.setAttribute(JobUIConstants.JOB_CREATION_SUCCESSFUL,
					JobUIConstants.JOB_CREATION_SUCCESSFUL);
		} else {
			request.setAttribute(JobUIConstants.JOB_CREATION_FAILED,
					JobUIConstants.JOB_CREATION_FAILED);
		}

		// this name should be the same as in pmm_menu_selection
		if (jobform.getEntityType().equalsIgnoreCase(EntityType.PARTNER.toString())) {
			request.setAttribute("TabbedPMMPartnersModify", "TabbedPMMPartnersModify");
		} else if (jobform.getEntityType().equalsIgnoreCase(EntityType.SERVICE.toString())) {
			request.setAttribute("TabbedPMMServicesModify", "TabbedPMMServicesModify");
		}

		return mapping.findForward(POST_CREATE_UPDATE);
	}

	public ActionForward updateJob(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception {

		JobForm jobform = (JobForm) form;

		// prepare the job object from the form and send it to the job manager
		IJobManager jobMgr = JobManager.getInstance();		

		Job job = jobMgr.getJob(jobform.getId());

		job.setName(jobform.getName());
		job.setPriority(ProcessPriority.valueOf(jobform.getSelectedPriority()));
		updateJobParameters(job, jobform.getJobParamNames(), jobform.getValue());
		updateJobRule(job, jobform);

		if (jobMgr.updateJob(job)) {
			request.setAttribute(JobUIConstants.JOB_UPDATE_SUCCESSFUL,
					JobUIConstants.JOB_UPDATE_SUCCESSFUL);
		} else {
			request
					.setAttribute(JobUIConstants.JOB_UPDATE_FAILED,
							JobUIConstants.JOB_UPDATE_FAILED);
		}

		// this name should be the same as in pmm_menu_selection
		if (jobform.getEntityType().equalsIgnoreCase(EntityType.PARTNER.toString())) {
			request.setAttribute("TabbedPMMPartnersModify", "TabbedPMMPartnersModify");
		} else if (jobform.getEntityType().equalsIgnoreCase(EntityType.SERVICE.toString())) {
			request.setAttribute("TabbedPMMServicesModify", "TabbedPMMServicesModify");
		}

		return mapping.findForward(POST_CREATE_UPDATE);
	}

	/**
	 * this method updates the values of the rule parameters if the ruletype is still the same or
	 * else creates a new rule with rule types and associates that with the job.
	 * 
	 * @param job
	 * @param jobform
	 */
	@SuppressWarnings("unchecked")
	private void updateJobRule(Job job, JobForm jobform) {

		// if the selected rule type is the same as before
		// simply update the values of the rule parameters.
		List<RuleParameter> ruleParamList = job.getRule().getParams();

		if (jobform.getSelectedRuleType().equalsIgnoreCase(job.getRule().getType().getName())) {
			List<RuleTypeParameter> ruleTypeParamList = job.getRule().getType().getParams();
			String[] ruleParamValues = JobFormPopulator.getRuleParamsForSelectedRule(jobform);
			for (int i = 0; i < ruleTypeParamList.size(); i++) {
				if (!ruleTypeParamList.get(i).getIsRequired() && ruleParamValues[i] == null
						|| ruleParamValues[i].trim().length() == 0) {
					// currently only dates and times are optional so only filling in for a date
					if (ruleTypeParamList.get(i).getType() == RuleParameterDataType.DATE)
						ruleParamList.get(i).setValue(new Date().toString());
					else if (ruleTypeParamList.get(i).getType() == RuleParameterDataType.TIME)
						ruleParamList.get(i).setValue(DEFAULT_TIME);
					else
						ruleParamList.get(i).setValue(ruleParamValues[i]);
				} else {
					ruleParamList.get(i).setValue(ruleParamValues[i]);
				}
			}
		} else {
			// else update the ruletype for the existing rule and update its parameters
			// if the parameter count = new ruletype paramter count, simply update the value
			// if paramter count > new rule type parameter count, delete the extra parameters
			// if parameter count < new rule type parameter count, create a new one and set the
			// value and rule

			// NOTE: if there are extra parameters then they are not really deleted from the db
			// (just like the job paramters)
			// but these will not show in the UI as the iteration is based on the rule type's
			// parameter list

			IJobManager jobMgr = JobManager.getInstance();

			RuleType ruleType = jobMgr.getRuleType(jobform.getSelectedRuleType());
			job.getRule().setType(ruleType);
			List<RuleTypeParameter> ruleTypeParamList = ruleType.getParams();
			String[] ruleParamValues = JobFormPopulator.getRuleParamsForSelectedRule(jobform);
			if (ruleParamList.size() == ruleTypeParamList.size()) {
				// do nothing
			} else if (ruleParamList.size() < ruleTypeParamList.size()) {
				// create new parameters
				int additionalParamCount = ruleTypeParamList.size() - ruleParamList.size();
				for (int i = 0; i < additionalParamCount; i++) {
					RuleParameter parameter = new RuleParameter();
					// new entry index
					parameter.setOrder(ruleParamList.size() + 1);
					ruleParamList.add(parameter);
				}
			} else if (ruleParamList.size() > ruleTypeParamList.size()) {
				int extraParameterCount = ruleParamList.size() - ruleTypeParamList.size();
				for (int i = 0; i < extraParameterCount; i++) {
					ruleParamList.remove(ruleParamList.get(ruleParamList.size() - 1));
				}
			}
			// set the rule and value for all params now
			for (int i = 0; i < ruleParamList.size(); i++) {
				ruleParamList.get(i).setRule(job.getRule());
				ruleParamList.get(i).setValue(ruleParamValues[i]);
			}
		}

		RuleTypeInfoLoader infoLoader = RuleTypeInfoLoader.getInstance();
		String timeClass = infoLoader.getTimerClass(jobform.getSelectedRuleType());
		job.getRule().setTimeClass(timeClass);

		RuleCallbackClassFinder callbackFinder = new RuleCallbackClassFinder();

		EntityType type = EntityType.valueOf(jobform.getEntityType());
		// if this is a partner check if its a self or a distribution/source partner.
		// Self partner has different properties than distribution/source.
		if (type == EntityType.PARTNER) {
			ICacheService<IContainer> containerCache = (ICacheService<IContainer>) ServiceRegistry
					.getDefault().lookup(CONTAINER_CACHE_SERVICE_NAME);
			Partner container = (Partner) containerCache.get(job.getContext().getId());
			PartnerType partnerType = container.getType();
			if (partnerType == PartnerType.SELF) {
				type = EntityType.SELF;
			}
		}
		String callbackClass = callbackFinder.getCallbackClass(Boolean.valueOf(jobform
				.getIsAssociatedWithTitles()), type, ruleParamList, job.getRule().getType()
				.getParams());
		job.getRule().setCallbackClass(callbackClass);

		job.getRule().setStartDate(getStartDate(jobform));
		job.getRule().setEndDate(getEndDate(jobform));
	}

	/**
	 * This method updates the already existing job parameters with the new values If a parameter is
	 * removed because the template no lnger has that variable, the parameter is deleted.
	 * 
	 * @param job
	 * @param jobParamNames
	 * @param value
	 * @return
	 */
	private void updateJobParameters(Job job, String jobParamNames, String[] value) {

		// go thru all the param names and match them with the existing parameters
		// if not found, create a new one
		String[] namesList = jobParamNames.split(PARAMETER_NAME_DELIMETER);
		List<JobParameter> jobParams = job.getJobParams();
		for (int i = 0; i < namesList.length; i++) {
			int index = getParameterIndex(namesList[i], jobParams);
			if (index != INVALID_INDEX) {
				jobParams.get(index).setValue(value[i]);
			} else {
				JobParameter parameter = new JobParameter();
				parameter.setJob(job);
				parameter.setName(namesList[i]);
				parameter.setValue(value[i]);

				jobParams.add(parameter);
			}
		}

		// then iterate thru the existing parameters to see if any of them were deleted by matching
		// them
		// with the name list. If yes, then delete such parameters
		// for (JobParameter parameter : jobParams)
		List<Integer> paramsToRemoveIndex = new ArrayList<Integer>();
		for (int i = 0; i < jobParams.size(); i++) {
			JobParameter parameter = jobParams.get(i);
			int index = getVariableIndex(parameter.getName(), namesList);
			if (index == INVALID_INDEX) {
				// jobParams.remove(parameter);
				paramsToRemoveIndex.add(Integer.valueOf(i));
			}
		}
		for (int i = 0; i < paramsToRemoveIndex.size(); i++) {
			jobParams.remove((int) paramsToRemoveIndex.get(i));
		}
	}

	/**
	 * @param job
	 * @param jobform
	 */
	private void setJobRuleValueInfo(Job job, JobForm jobform) {
		jobform.setRuleId(job.getRule().getId());

		// set the values in the dummy rule parameter form that were created as part of setting up
		// required fields
		List<RuleParameterForm> forms = jobform.getRuleParameters().get(
				jobform.getSelectedRuleType());
		for (int i = 0; i < forms.size(); i++) {
			forms.get(i).setRuleParamValue(job.getRule().getParams().get(i).getValue());
		}
	}

	/**
	 * @param job
	 * @param jobform
	 */
	private void setJobParameterValueInfo(Job job, JobForm jobform) {

		// get the selected template name from the job
		// get the variables for this template
		// for each template var, get the value from the list of existing parameter list
		// and add it to the string[]
		// also add the mapped name in the names[]
		// prepare jobparameterform objects for each variable of the template

		// NOTE: Any variables that are removed will still be left over in the db but not displayed
		// as the parameters are created from the current variables in the template.

		Collection<TaskVariable> variables = JobFormPopulator.getTemplateParameters(job
				.getTemplateName());
		TaskVariable[] variableList = new TaskVariable[variables.size()];
		StringBuilder parameterNames = new StringBuilder();
		String[] parameterValues = new String[variables.size()];
		variableList = variables.toArray(variableList);
		for (int i = 0; i < variableList.length; i++) {
			if (parameterNames.length() > 0)
				parameterNames.append(PARAMETER_NAME_DELIMETER);
			parameterNames.append(variableList[i].getMappedName());

			int index = getParameterIndex(variableList[i].getMappedName(), job.getJobParams());
			if (index != INVALID_INDEX)
				parameterValues[i] = job.getJobParams().get(index).getValue();
		}

		jobform.setJobParamNames(parameterNames.toString());
		jobform.setValue(parameterValues);
	}

	private int getParameterIndex(String parameterName, List<JobParameter> list) {
		for (int i = 0; i < list.size(); i++) {
			if (list.get(i).getName().equalsIgnoreCase(parameterName))
				return i;
		}
		return INVALID_INDEX;
	}

	/**
	 * @param variableName
	 *            variable name to be searched in the list provided
	 * @param list
	 *            the list in which the the name will be searched
	 * @return index in the list where the name is found in the list
	 */
	private static int getVariableIndex(String variableName, String[] list) {
		for (int i = 0; i < list.length; i++) {
			if (list[i].equalsIgnoreCase(variableName))
				return i;
		}
		return INVALID_INDEX;
	}

	/**
	 * @param jobform
	 * @return
	 */
	private Rule createRule(JobForm jobform) {
		IJobManager jobMgr = JobManager.getInstance();

		Rule jobRule = new Rule();
		jobRule.setId(jobform.getRuleId());
		RuleType ruleType = jobMgr.getRuleType(jobform.getSelectedRuleType());
		jobRule.setType(ruleType);
		String[] selectedRuleParams = JobFormPopulator.getRuleParamsForSelectedRule(jobform);
		List<RuleParameter> ruleParameters = createRuleParameters(jobRule, selectedRuleParams);
		jobRule.setParams(ruleParameters);

		jobRule.setStartDate(getStartDate(jobform));
		jobRule.setEndDate(getEndDate(jobform));

		RuleTypeInfoLoader infoLoader = RuleTypeInfoLoader.getInstance();
		String timeClass = infoLoader.getTimerClass(jobform.getSelectedRuleType());
		jobRule.setTimeClass(timeClass);

		RuleCallbackClassFinder callbackFinder = new RuleCallbackClassFinder();
		String callbackClass = callbackFinder.getCallbackClass(Boolean.valueOf(jobform
				.getIsAssociatedWithTitles()), EntityType.valueOf(jobform.getEntityType()),
				ruleParameters, ruleType.getParams());
		jobRule.setCallbackClass(callbackClass);

		return jobRule;
	}

	/**
	 * @param jobform
	 */
	private Date getEndDate(JobForm jobform) {
		SimpleDateFormat timefomat = new SimpleDateFormat(DATE_FORMAT);
		timefomat.setLenient(false); // this is important!
		// if end date is not provided dont fill in anything
		Date endDate = null;

		if (jobform.getJobEndDate() != null && jobform.getJobEndDate().trim().length() > 0) {
			try {
				endDate = timefomat.parse(jobform.getJobEndDate());
			} catch (ParseException e) {
				logger.error("Error while parsing end date: " + e.toString());
			}
		}

		return endDate;
	}

	/**
	 * @param jobform
	 */
	private Date getStartDate(JobForm jobform) {
		SimpleDateFormat timefomat = new SimpleDateFormat(DATE_FORMAT);
		timefomat.setLenient(false); // this is important!
		Date startDate = new Date();
		if (jobform.getJobStartDate() != null && jobform.getJobStartDate().trim().length() > 0) {
			try {
				startDate = timefomat.parse(jobform.getJobStartDate());
			} catch (ParseException e) {
				logger.error("Error while parsing start date: " + e.toString());
			}
		}
		return startDate;
	}

	/**
	 * @param jobParamNames
	 * @param value
	 * @return
	 */
	private List<JobParameter> createJobParameters(Job parent, String names, String[] values) {

		List<JobParameter> jobParameters = new ArrayList<JobParameter>();

		String[] parameterNames = names.split(PARAMETER_NAME_DELIMETER);
		for (int i = 0; i < parameterNames.length; i++) {
			JobParameter parameter = new JobParameter();
			parameter.setJob(parent);
			parameter.setName(parameterNames[i]);
			parameter.setValue(values[i]);
			jobParameters.add(parameter);
		}
		return jobParameters;
	}

	/**
	 * @param rule
	 * @param ruleParamValue
	 * @return
	 */
	private List<RuleParameter> createRuleParameters(Rule rule, String[] ruleParamValue) {
		List<RuleParameter> ruleParameters = new ArrayList<RuleParameter>();

		for (int i = 0; i < rule.getType().getParams().size(); i++) {
			RuleTypeParameter currRuletypeParameter = rule.getType().getParams().get(i);
			RuleParameter parameter = new RuleParameter();

			// fill up optional values with default values if not provided
			if (!currRuletypeParameter.getIsRequired() && ruleParamValue[i] == null
					|| ruleParamValue[i].trim().length() == 0) {
				// currently only dates are optional so only filling in for a date
				if (currRuletypeParameter.getType() == RuleParameterDataType.DATE)
					parameter.setValue(new Date().toString());
				else if (currRuletypeParameter.getType() == RuleParameterDataType.TIME)
					parameter.setValue(DEFAULT_TIME);
				else
					parameter.setValue(ruleParamValue[i]);
			} else {
				parameter.setValue(ruleParamValue[i]);
			}

			parameter.setRule(rule);
			// TODO: can this number be generated by list in hbm?
			// 1 based order
			parameter.setOrder(i + 1);

			ruleParameters.add(parameter);
		}
		return ruleParameters;
	}

	/**
	 * @param variables
	 *            list of task variables whose names will be copied into the jobform
	 * @param jobform
	 *            jobform instance where the names will be copied into
	 */
	private void setJobParamNames(Collection<TaskVariable> variables, JobForm jobform) {
		TaskVariable taskVariables[] = new TaskVariable[variables.size()];
		taskVariables = variables.toArray(taskVariables);
		StringBuilder parameterNames = new StringBuilder();
		for (int i = 0; i < taskVariables.length; i++) {
			if (parameterNames.length() > 0)
				parameterNames.append(PARAMETER_NAME_DELIMETER);

			parameterNames.append(taskVariables[i].getMappedName());
		}
		jobform.setJobParamNames(parameterNames.toString());
	}
	
	/** 
	 * Sets the selectedRuleType to the first in the list
	 * @param jobform
	 */
	private void setSelectedRuleTypeToDefault(JobForm jobform) {
		IJobManager jobMgr = JobManager.getInstance();
		List<RuleType> rules = jobMgr.getRuleTypes(Boolean.valueOf(jobform
				.getIsAssociatedWithTitles()));
		logger.debug("setting selectedRuleType to " + rules.get(0).getName());
		jobform.setSelectedRuleType(rules.get(0).getName());
	}
}
