/**
 * MediaPathDispatcher.java
 * Created on Jul 28, 2008
 * (C) Copyright TANDBERG Television Ltd.
 */
package com.tandbergtv.workflow.adaptor.dispatcher;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Properties;

import javax.xml.rpc.ServiceException;
import javax.xml.rpc.Stub;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;

import com.systinet.wsdl.com.n2bb.manager.webservice.server.JavaServiceLocator;
import com.systinet.wsdl.com.n2bb.manager.webservice.server.SchedulerService;
import com.tandbergtv.workflow.adaptor.conf.DispatcherParameter;
import com.tandbergtv.workflow.adaptor.conf.IDispatcherConfiguration;
import com.tandbergtv.workflow.comm.HTTPDevice;
import com.tandbergtv.workflow.comm.IDestination;
import com.tandbergtv.workflow.message.HTTPMessage;
import com.tandbergtv.workflow.message.HTTPPayload;
import com.tandbergtv.workflow.message.IMessage;
import com.tandbergtv.workflow.message.WorkflowMessage;
import com.tandbergtv.workflow.message.util.MarshalException;
import com.tandbergtv.workflow.message.util.Marshaller;
import com.tandbergtv.workflow.util.XMLDocumentUtility;

/**
 * Abstract Dispatcher class for MediaPath dispatchers
 * 
 * @author Vlada Jakobac
 * 
 */
public abstract class MediaPathDispatcher extends AbstractDispatcher {

	private static final Logger logger = Logger
			.getLogger(MediaPathDispatcher.class);
	
	public static String LOGIN_PROPERTIES = "/adaptor/mediaPath.properties";
											
	public static final String UNKNOWN = "UNKNOWN";
	public static final String IN_QUEUE = "IN_QUEUE";
	public static final String IN_PROGRESS = "IN_PROGRESS";
	public static final String SUCCESS = "SUCCESS";
	public static final String ATTEMPTED = "ATTEMPTED";
	public static final String STOP_REQUESTED = "STOP_REQUESTED";
	public static final String STOPPED = "STOPPED";
	public static final String FAILED = "FAILED";
	public static final String DELETED = "DELETED";
	public static final String ENCRYPTING = "ENCRYPTING";

	public static final int SUCCESS_FLAG = 2;

	public MediaPathDispatcher(IDispatcherConfiguration conf,
			IDestination destination) {
		super(conf, destination);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.tandbergtv.workflow.adaptor.dispatcher.IDispatcher#send(com.tandbergtv.workflow.message.IMessage)
	 */
	public IMessage send(IMessage msg) throws DispatcherException {
		URL url = null;

		logger.debug("Sending message to: " + getDestination());

		try {
			url = new URL(((HTTPDevice) getDestination()).getUrl());
			URLConnection conn = url.openConnection();

			logger.debug("URL=" + url.toString());
			String timeout = (String) getConfiguration().getParameterValue(
					DispatcherParameter.CONNECTION_TIMEOUT);
			if (timeout != null) {
				try {
					logger.debug("Timeout read from the config : " + timeout);
					int connectTimeout = Integer.parseInt(timeout);
					conn.setConnectTimeout(connectTimeout * 1000);
				} catch (Exception ex) {
					logger.error("Timeout specified " + timeout
							+ " is not an integer."
							+ " It should be an integer value in seconds.");
				}
			}

			WorkflowMessage response = generateResponse(msg, url);
			Document docResponse = Marshaller.newMarshaller().marshal(response);

			HTTPPayload httpPayload = new HTTPPayload(XMLDocumentUtility
					.convertToString(docResponse));
			HTTPMessage responseMsg = new HTTPMessage(httpPayload);

			logger.debug("Generated message: " + responseMsg);

			return responseMsg;
		} catch (MalformedURLException ex) {
			String errMsg = "Invalid url: " + url;
			throw new DispatcherException(errMsg, ex);
		} catch (IOException ex) {
			String errMsg = "Could not open a connection to destination URL:" + url;
			throw new DispatcherException(errMsg, ex);

		} catch (MarshalException e) {
			String errMsg = "Could not marshal the document from: " + url;
			throw new DispatcherException(errMsg, e);

		} catch (Exception e) {
			String errMsg = "Could not parse the response from: " + url;
			throw new DispatcherException(errMsg, e);

		}

	}

	/**
	 * Method that generates a Workflow Message response based on the RPC call
	 * using the MediaPath proxy
	 * 
	 * @param msg
	 *            Incoming message
	 * @param url
	 *            Resource URL
	 * @return Response message
	 */
	protected abstract WorkflowMessage generateResponse(IMessage msg, URL url)
			throws DispatcherException;

	protected SchedulerService getService(URL url) throws MediaPathAPIException, IOException{
		
		InputStream stream = this.getClass().getResourceAsStream(LOGIN_PROPERTIES);
		Properties config = new Properties();
		config.load(stream);
		logger.debug("successfully loaded the stream");
	
		String username = config.getProperty("username");
		String password = config.getProperty("password");
		
		SchedulerService service = null;

		JavaServiceLocator locator = new JavaServiceLocator();

		try {
			service = locator.getSchedulerService(url);
			((Stub) service)._setProperty(Stub.USERNAME_PROPERTY, username);
			((Stub) service)._setProperty(Stub.PASSWORD_PROPERTY, password);
			return service;
		} catch (ServiceException e) {
			throw new MediaPathAPIException(e);
		}

	}

}
