/*
 * Created on Jul 7, 2008 (C) Copyright TANDBERG Television Ltd.
 */

package com.tandbergtv.watchpoint.pmm.communication.handlers;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.tandbergtv.watchpoint.pmm.communication.HandlerErrorCode;
import com.tandbergtv.watchpoint.pmm.communication.MessageHandler;
import com.tandbergtv.watchpoint.pmm.communication.MessageHandlerException;
import com.tandbergtv.watchpoint.pmm.entities.DistributionSchedule;
import com.tandbergtv.watchpoint.pmm.entities.Schedule;
import com.tandbergtv.watchpoint.pmm.schedule.ISchedulePersistenceService;
import com.tandbergtv.watchpoint.pmm.schedule.search.IScheduleSearchService;
import com.tandbergtv.workflow.core.service.ServiceRegistry;
import com.tandbergtv.workflow.message.IMessageKey;
import com.tandbergtv.workflow.message.IMessageUID;
import com.tandbergtv.workflow.message.WorkflowMessage;
import com.tandbergtv.workflow.message.WorkflowMessage.MessageType;

/**
 * @author Vijay Silva
 */
public class CreateScheduleMessageHandler implements MessageHandler {

	/* The Context Id in the input message */
	private static final String CONTEXT_ID_PARAM = "contextId";

	/* The Pitch Date for Schedule in the input message */
	private static final String PITCH_DATE_PARAM = "pitchDate";

	/* The Source Partner Id (optional) in the input message */
	private static final String SOURCE_PARTNER_ID_PARAM = "sourcePartnerId";

	/* The Schedule Id for the schedule created in the output message */
	private static final String SCHEDULE_ID_PARAM = "scheduleId";

	/* The Date Format for the date present in the message */
	private static final String DATE_FORMAT = "yyyy-MM-dd";

	/**
	 * Creates a new Schedule using the input Pitch date and the Context Id of the Partner or
	 * Service for which this Schedule is being created.
	 * 
	 * @see com.tandbergtv.watchpoint.pmm.communication.MessageHandler#handleMessage(com.tandbergtv.workflow.message.WorkflowMessage)
	 */
	public WorkflowMessage handleMessage(WorkflowMessage message) throws Exception {
		/* Get the inputs from the message */
		long contextId = this.getLongParameter(message, CONTEXT_ID_PARAM, false);
		Date pitchDate = this.getDateParameter(message, PITCH_DATE_PARAM);
		Long sourcePartnerId = this.getLongParameter(message, SOURCE_PARTNER_ID_PARAM, true);

		/* If the Source Partner Id is a value less than or equal to 0, use default null value */
		if (sourcePartnerId != null && sourcePartnerId.longValue() <= 0)
			sourcePartnerId = null;

		ServiceRegistry registry = ServiceRegistry.getDefault();
		IScheduleSearchService search = registry.lookup(IScheduleSearchService.class);
		
		if (search.getPitchSchedulesByPitchDate(Long.valueOf(contextId), pitchDate).size() > 0)
			throw new MessageHandlerException(HandlerErrorCode.RUNTIME_ERROR, 
				"Pitch schedule already exists for the specified date");

		/* Create the new Schedule */
		Schedule schedule = new DistributionSchedule(sourcePartnerId, contextId, pitchDate);

		ISchedulePersistenceService service = registry.lookup(ISchedulePersistenceService.class);
		service.save(schedule);

		/* Build the Workflow Message Response */
		IMessageUID uid = message.getMessageUID();
		IMessageKey key = message.getKey();
		WorkflowMessage response = new WorkflowMessage(uid, key, MessageType.ack);
		response.putValue(SCHEDULE_ID_PARAM, Long.toString(schedule.getId()));

		return response;
	}

	/* Get a Long Parameter from the Workflow Message */
	private Long getLongParameter(WorkflowMessage message, String name, boolean optional)
			throws MessageHandlerException {
		Long result = null;

		String value = (message.getPayload() != null) ? message.getValue(name) : null;
		if (value == null || value.trim().length() == 0) {
			if (optional)
				return result;

			throw new MessageHandlerException(HandlerErrorCode.INVALID_INPUT, "The " + name
					+ " message parameter is blank / missing when a number value was expected.");
		}

		try {
			result = new Long(value);
		} catch (Exception e) {
			throw new MessageHandlerException(HandlerErrorCode.INVALID_INPUT, "The " + name
					+ " message parameter does not have a valid number value, received value: "
					+ value, e);
		}

		return result;
	}

	/* Get a Date Parameter from the Workflow Message */
	private Date getDateParameter(WorkflowMessage message, String name)
			throws MessageHandlerException {
		Date result = null;

		String value = (message.getPayload() != null) ? message.getValue(name) : null;
		if (value == null || value.trim().length() == 0) {
			throw new MessageHandlerException(HandlerErrorCode.INVALID_INPUT, "The " + name
					+ " message parameter is blank / missing when a date value was expected.");
		}

		try {
			DateFormat format = new SimpleDateFormat(DATE_FORMAT);
			result = format.parse(value);
		} catch (Exception e) {
			throw new MessageHandlerException(HandlerErrorCode.INVALID_INPUT, "The " + name
					+ " message parameter does not have a valid date value. Expected format: "
					+ DATE_FORMAT + ", received value: " + value, e);
		}

		return result;
	}
}
