/**
 * PackageIngestionDispatcher.java
 * Created on Jul 28, 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 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.common._package;
import com.systinet.wsdl.com.n2bb.manager.webservice.server.SchedulerService;
import com.systinet.wsdl.com.n2bb.manager.webservice.server.SchedulerService_getPackages_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 PackageIngestionDispatcher extends MediaPathDispatcher {

	private static final Logger logger = Logger
			.getLogger(PackageIngestionDispatcher.class);

	/**
	 * Class Constructor
	 * 
	 * @param conf
	 *            Dispatcher Configuration
	 * @param destination
	 *            The target Destination
	 */
	public PackageIngestionDispatcher(IDispatcherConfiguration conf,
			IDestination destination) {
		super(conf, destination);
	}

	@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 providerId = null, assetId = null, minorVersion = null, majorVersion = null;
			XPath xpath = XPathFactory.newInstance().newXPath();
			Node parameterListNode = (Node) xpath.evaluate(
					"//WFSMessage/MessageBody/ParameterList", doc,
					XPathConstants.NODE);
			if (parameterListNode != null) {
				Node providerIdNode = (Node) xpath.evaluate(
						"Parameter[@Name='ProviderId']", parameterListNode,
						XPathConstants.NODE);
				if (providerIdNode != null) {
					providerId = (String) xpath.evaluate("Value",
							providerIdNode, XPathConstants.STRING);
				}
				Node assetIdNode = (Node) xpath.evaluate(
						"Parameter[@Name='AssetId']", parameterListNode,
						XPathConstants.NODE);
				if (assetIdNode != null) {
					assetId = (String) xpath.evaluate("Value", assetIdNode,
							XPathConstants.STRING);
				}
				Node minorVersionNode = (Node) xpath.evaluate(
						"Parameter[@Name='MinorVersion']", parameterListNode,
						XPathConstants.NODE);
				if (minorVersionNode != null) {
					minorVersion = (String) xpath.evaluate("Value",
							minorVersionNode, XPathConstants.STRING);
				}
				Node majorVersionNode = (Node) xpath.evaluate(
						"Parameter[@Name='MajorVersion']", parameterListNode,
						XPathConstants.NODE);
				if (majorVersionNode != null) {
					majorVersion = (String) xpath.evaluate("Value",
							majorVersionNode, 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 {
				/* Make the proxy call to the webservice */
				SchedulerService service = getService(url);
				String packageId = getPackageId(service, providerId, assetId,
						minorVersion, majorVersion);

				payload.putValue("PackageId", packageId);
				response.setType(MessageType.ack);
			} catch (MediaPathAPIException de) {
				logger.error("Error occurred whilce getting packages: ", de);
				StringWriter writer = new StringWriter();
				de.printStackTrace(new PrintWriter(writer));
				payload.putValue("error-message", de.getMessage());
				payload.putValue("error-stack", writer.toString());
				response.setType(MessageType.nack);

			}
			return response;
		} catch (Exception e) {
			logger.error("Error while loading XML document", e);
			throw new DispatcherException(e);
		}
	}

	private String getPackageId(SchedulerService service, String providerId,
			String assetId, String minorVersion, String majorVersion)
			throws MediaPathAPIException {
		String packageId = "";

		_package[] packages;
		try {
			packages = service.getPackages();
		} catch (SchedulerService_getPackages_comN2BbManagerWebserviceCommonServiceException_Fault e) {
			throw new MediaPathAPIException(e);
		} catch (RemoteException e) {
			throw new MediaPathAPIException(e);
		}
		for (int i = 0; i < packages.length; i++) {
			boolean assId = packages[i].getAssetInfo().getAssetID().equals(
					assetId);
			if (assId){
				boolean provId = packages[i].getAssetInfo().getProviderID().equals(
						providerId);
				if (provId){
					boolean majVer = packages[i].getAssetInfo().getVersionMajor()
							.toString().equals(majorVersion);
					boolean minVer = packages[i].getAssetInfo().getVersionMinor()
							.toString().equals(minorVersion);					
					if (majVer && minVer) {
						packageId = packages[i].getId().toString();
						logger.debug("Package ingested, id=" + packageId);
						break;
					}
				}				
			}			
		}
		return packageId;
	}

}
