/**
 * ReschedulePitchDispatcher.java
 * Created on Jul 29, 2008
 * (C) Copyright TANDBERG Television Ltd.
 */
package com.tandbergtv.workflow.adaptor.dispatcher;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.rmi.RemoteException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import com.systinet.wsdl.com.n2bb.manager.webservice.server.SchedulerService;
import com.systinet.wsdl.com.n2bb.manager.webservice.server.SchedulerService_reschedule_comN2BbManagerWebserviceCommonServiceException_Fault;
import com.tandbergtv.workflow.adaptor.conf.IDispatcherConfiguration;
import com.tandbergtv.workflow.comm.IDestination;
import com.tandbergtv.workflow.message.IMessage;
import com.tandbergtv.workflow.message.MessageKeyImpl;
import com.tandbergtv.workflow.message.MessageUIDImpl;
import com.tandbergtv.workflow.message.WorkflowMessage;
import com.tandbergtv.workflow.message.WorkflowPayload;
import com.tandbergtv.workflow.message.WorkflowMessage.MessageType;
import com.tandbergtv.workflow.util.XMLDocumentUtility;

/**
 * @author Vlada Jakobac
 *
 */
public class ReschedulePitchDispatcher extends MediaPathDispatcher {

	private static final Logger logger = Logger.getLogger(ReschedulePitchDispatcher.class);

	/* The Date Format for the date present in the message */
	private static final String DATE_FORMAT = "EEE MMM d HH:mm:ss z yyyy";

	public ReschedulePitchDispatcher(IDispatcherConfiguration conf,
			IDestination destination) {
		super(conf, destination);
		
	}

	/* (non-Javadoc)
	 * @see com.tandbergtv.workflow.adaptor.dispatcher.MediaPathDispatcher#generateResponse(com.tandbergtv.workflow.message.IMessage, java.net.URL)
	 */
	@Override
	protected WorkflowMessage generateResponse(IMessage msg, URL url)
			throws DispatcherException {
		logger.debug("payload=" + msg.getPayload().getContent());
		Document doc;
		try {
			doc = XMLDocumentUtility.loadXml(msg.getPayload().getContent());	
			
			String pitchId = null, rescheduleDate=null;
			XPath xpath = XPathFactory.newInstance().newXPath();
			Node parameterListNode = (Node) xpath.evaluate("//WFSMessage/MessageBody/ParameterList", doc, XPathConstants.NODE);
			if(parameterListNode != null) {
				Node pitchIdNode = (Node) xpath.evaluate("Parameter[@Name='PitchId']", parameterListNode, XPathConstants.NODE);
				if(pitchIdNode != null) {
					pitchId = (String) xpath.evaluate("Value", pitchIdNode, XPathConstants.STRING);					
				}
				Node rescheduleDateNode = (Node) xpath.evaluate("Parameter[@Name='RescheduleDate']", parameterListNode, XPathConstants.NODE);
				if(rescheduleDateNode != null) {
					rescheduleDate = (String) xpath.evaluate("Value", rescheduleDateNode, XPathConstants.STRING);					
				}
			}
			
			Node wfsMessageNode = (Node) xpath.evaluate("//WFSMessage", doc, XPathConstants.NODE);
			
			String messUID = (String) wfsMessageNode.getAttributes().getNamedItem("UID").getTextContent();
			String requestKey = (String) wfsMessageNode.getAttributes().getNamedItem("RequestKey").getTextContent();
			logger.debug("messUID="+messUID+", requestKey="+requestKey);
			WorkflowMessage response = new WorkflowMessage(new MessageUIDImpl(messUID), new MessageKeyImpl(requestKey));
			WorkflowPayload payload = (WorkflowPayload) response.getPayload();
			
			try {
				SchedulerService service = getService(url);
				String rescheduledPitchId = getRescheduledPitchId(service, pitchId, rescheduleDate);
				if (rescheduledPitchId != null && !rescheduledPitchId.equals("")){
					payload.putValue("RescheduledPitchId", rescheduledPitchId);
					payload.putValue("PackageRescheduled", "true");
					response.setType(MessageType.ack);
				} else {
					payload.putValue("PackageRescheduled", "false");
					response.setType(MessageType.nack);
				}				
				
			} catch (MediaPathAPIException de){
				logger.error("Error occurred while getting the rescheduled pitch status for a package: ", de);
				StringWriter writer = new StringWriter();
				de.printStackTrace(new PrintWriter(writer));
				payload.putValue("error-message", de.getMessage());
				payload.putValue("PackageRescheduled", "false");
				response.setType(MessageType.nack);
				
			}
			return response;
		} catch (Exception e) {
			logger.error("Error while loading XML document", e);
			throw new DispatcherException(e);
		}

	}

	private String getRescheduledPitchId(SchedulerService service, String pitchId,
			String rescheduleDate) throws MediaPathAPIException {
		String rescheduledPitchId = null;
		
	    Long[] rescheduledPitchIds;
		try {
			//set the new pitch date
			DateFormat format = new SimpleDateFormat(DATE_FORMAT);
			Calendar pitchDate = Calendar.getInstance();
		    pitchDate.setTime(format.parse(rescheduleDate));
		    
			rescheduledPitchIds = service.reschedule(Long.valueOf(pitchId), pitchDate);
		} catch (SchedulerService_reschedule_comN2BbManagerWebserviceCommonServiceException_Fault e) {
			throw new MediaPathAPIException(e);
		} catch (NumberFormatException e) {
			throw new MediaPathAPIException(e);
		} catch (RemoteException e) {
			throw new MediaPathAPIException(e);
		} catch (ParseException e) {
			throw new MediaPathAPIException(e);
		} 
	    rescheduledPitchId = rescheduledPitchIds[0].toString();

		return rescheduledPitchId;

	}

}
