/*******************************************************************************
 * Copyright (C) 2007 The University of Manchester
 *
 *  Modifications to the initial code base are copyright of their
 *  respective authors, or their employers as appropriate.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1 of
 *  the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 ******************************************************************************/
package net.sf.taverna.t2.activities.wsdl;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.wsdl.WSDLException;
import javax.xml.parsers.ParserConfigurationException;

import net.sf.taverna.t2.reference.ReferenceService;
import net.sf.taverna.t2.reference.ReferenceServiceException;
import net.sf.taverna.t2.reference.T2Reference;
import net.sf.taverna.t2.security.credentialmanager.CredentialManager;
import net.sf.taverna.t2.workflowmodel.OutputPort;
import net.sf.taverna.t2.workflowmodel.health.RemoteHealthChecker;
import net.sf.taverna.t2.workflowmodel.processor.activity.AbstractAsynchronousActivity;
import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityConfigurationException;
import net.sf.taverna.t2.workflowmodel.processor.activity.ActivityOutputPort;
import net.sf.taverna.t2.workflowmodel.processor.activity.AsynchronousActivityCallback;
import net.sf.taverna.wsdl.parser.TypeDescriptor;
import net.sf.taverna.wsdl.parser.UnknownOperationException;
import net.sf.taverna.wsdl.parser.WSDLParser;

import org.apache.log4j.Logger;
import org.xml.sax.SAXException;

import com.fasterxml.jackson.databind.JsonNode;

/**
 * An asynchronous Activity that is concerned with WSDL based web-services.
 * <p>
 * The activity is configured according to the WSDL location and the operation.<br>
 * The ports are defined dynamically according to the WSDL specification, and in
 * addition an output<br>
 * port <em>attachmentList</em> is added to represent any attachements that are
 * returned by the webservice.
 * </p>
 *
 * @author Stuart Owen
 * @author Stian Soiland-Reyes
 */
public class WSDLActivity extends
		AbstractAsynchronousActivity<JsonNode> implements
		InputPortTypeDescriptorActivity, OutputPortTypeDescriptorActivity {

	public static final String URI = "http://ns.taverna.org.uk/2010/activity/wsdl";

	public static final String ENDPOINT_REFERENCE = "EndpointReference";
	private JsonNode configurationBean;
	private WSDLParser parser;
//	private Map<String, Integer> outputDepth = new HashMap<String, Integer>();
	private boolean isWsrfService = false;
//	private String endpointReferenceInputPortName;
	private CredentialManager credentialManager;

	public WSDLActivity(CredentialManager credentialManager) {
		this.credentialManager = credentialManager;
	}

	public boolean isWsrfService() {
		return isWsrfService;
	}

	private static Logger logger = Logger.getLogger(WSDLActivity.class);

	/**
	 * Configures the activity according to the information passed by the
	 * configuration bean.<br>
	 * During this process the WSDL is parsed to determine the input and output
	 * ports.
	 *
	 * @param bean
	 *            the {@link WSDLActivityConfigurationBean} configuration bean
	 */
	@Override
	public void configure(JsonNode bean)
			throws ActivityConfigurationException {
		this.configurationBean = bean;
		try {
			parseWSDL();
		} catch (Exception ex) {
			throw new ActivityConfigurationException(
					"Unable to parse the WSDL " + bean.get("operation").get("wsdl").textValue(), ex);
		}
	}

	@Override
	public JsonNode getConfiguration() {
		return configurationBean;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @seenet.sf.taverna.t2.activities.wsdl.InputPortTypeDescriptorActivity#
	 * getTypeDescriptorForInputPort(java.lang.String)
	 */
	public TypeDescriptor getTypeDescriptorForInputPort(String portName)
			throws UnknownOperationException, IOException {
		List<TypeDescriptor> inputDescriptors = parser
				.getOperationInputParameters(configurationBean.get("operation").get("name").textValue());
		TypeDescriptor result = null;
		for (TypeDescriptor descriptor : inputDescriptors) {
			if (descriptor.getName().equals(portName)) {
				result = descriptor;
				break;
			}
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @seenet.sf.taverna.t2.activities.wsdl.InputPortTypeDescriptorActivity#
	 * getTypeDescriptorsForInputPorts()
	 */
	public Map<String, TypeDescriptor> getTypeDescriptorsForInputPorts()
			throws UnknownOperationException, IOException {
		Map<String, TypeDescriptor> descriptors = new HashMap<String, TypeDescriptor>();
		List<TypeDescriptor> inputDescriptors = parser
				.getOperationInputParameters(configurationBean.get("operation").get("name").textValue());
		for (TypeDescriptor descriptor : inputDescriptors) {
			descriptors.put(descriptor.getName(), descriptor);
		}
		return descriptors;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @seenet.sf.taverna.t2.activities.wsdl.OutputPortTypeDescriptorActivity#
	 * getTypeDescriptorForOutputPort(java.lang.String)
	 */
	public TypeDescriptor getTypeDescriptorForOutputPort(String portName)
			throws UnknownOperationException, IOException {
		TypeDescriptor result = null;
		List<TypeDescriptor> outputDescriptors = parser
				.getOperationOutputParameters(configurationBean.get("operation").get("name").textValue());
		for (TypeDescriptor descriptor : outputDescriptors) {
			if (descriptor.getName().equals(portName)) {
				result = descriptor;
				break;
			}
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @seenet.sf.taverna.t2.activities.wsdl.OutputPortTypeDescriptorActivity#
	 * getTypeDescriptorsForOutputPorts()
	 */
	public Map<String, TypeDescriptor> getTypeDescriptorsForOutputPorts()
			throws UnknownOperationException, IOException {
		Map<String, TypeDescriptor> descriptors = new HashMap<String, TypeDescriptor>();
		List<TypeDescriptor> inputDescriptors = parser
				.getOperationOutputParameters(configurationBean.get("operation").get("name").textValue());
		for (TypeDescriptor descriptor : inputDescriptors) {
			descriptors.put(descriptor.getName(), descriptor);
		}
		return descriptors;
	}

	private void parseWSDL() throws ParserConfigurationException,
			WSDLException, IOException, SAXException, UnknownOperationException {
		String wsdlLocation = configurationBean.get("operation").get("wsdl").textValue();
		URLConnection connection = null;
		try {
			URL wsdlURL = new URL(wsdlLocation);
			connection = wsdlURL.openConnection();
			connection.setConnectTimeout(RemoteHealthChecker.getTimeoutInSeconds() * 1000);
			connection.connect();
		} catch (MalformedURLException e) {
			throw new IOException("Malformed URL", e);
		} catch (SocketTimeoutException e) {
			throw new IOException("Timeout", e);
		} catch (IOException e) {
			throw e;
		} finally {
			if ((connection != null) && (connection.getInputStream() != null)) {
				connection.getInputStream().close();
			}
		}
		parser = new WSDLParser(wsdlLocation);
		isWsrfService = parser.isWsrfService();
	}

	@Override
	public void executeAsynch(final Map<String, T2Reference> data,
			final AsynchronousActivityCallback callback) {

		callback.requestRun(new Runnable() {

			public void run() {

				ReferenceService referenceService = callback.getContext()
						.getReferenceService();

				Map<String, T2Reference> outputData = new HashMap<String, T2Reference>();
				Map<String, Object> invokerInputMap = new HashMap<String, Object>();
				String endpointReferenceInputPortName = getEndpointReferenceInputPortName();

				try {
					String endpointReference = null;
					for (String key : data.keySet()) {
						Object renderIdentifier = referenceService
								.renderIdentifier(data.get(key), String.class,
										callback.getContext());
						if (isWsrfService()
								&& key.equals(endpointReferenceInputPortName)) {
							endpointReference = (String) renderIdentifier;
						} else {
							invokerInputMap.put(key, renderIdentifier);
						}
					}
					List<String> outputNames = new ArrayList<String>();
					for (OutputPort port : getOutputPorts()) {
						outputNames.add(port.getName());
					}

					T2WSDLSOAPInvoker invoker = new T2WSDLSOAPInvoker(parser,
							configurationBean.get("operation").get("name").textValue(), outputNames,
							endpointReference, credentialManager);

					Map<String, Object> invokerOutputMap = invoker.invoke(
							invokerInputMap, configurationBean);
					
					for (String outputName : invokerOutputMap.keySet()) {
					    Object value = invokerOutputMap.get(outputName);
						
						if (value != null) {
							Integer depth = getOutputPortDepth(outputName);
							if (depth != null) {
								outputData.put(outputName, referenceService
										.register(value, depth, true, callback
												.getContext()));
							} else {
								logger.info("Skipping unknown output port :"
												+ outputName);
//								// TODO what should the depth be in this case?
//								outputData.put(outputName, referenceService
//										.register(value, 0, true, callback
//												.getContext()));
							}
						}
					}
					callback.receiveResult(outputData, new int[0]);
				} catch (ReferenceServiceException e) {
					logger.error("Error finding the input data for "
							+ getConfiguration().get("operation"), e);
					callback.fail("Unable to find input data", e);
					return;
				} catch (Exception e) {
					logger.error("Error invoking WSDL service "
							+ getConfiguration().get("operation"), e);
					callback.fail(
							"An error occurred invoking the WSDL service", e);
					return;
				}

			}

		});

	}

	private Integer getOutputPortDepth(String portName) {
		for (ActivityOutputPort outputPort : getOutputPorts()) {
			if (outputPort.getName().equals(portName)) {
				return outputPort.getDepth();
			}
		}
		return null;
	}

	private String getEndpointReferenceInputPortName() {
		String endpointReferenceInputPortName = null;
		if (parser.isWsrfService()) {
			Set<String> inputPorts = new HashSet<>();
			try {
				List<TypeDescriptor> inputDescriptors = parser.getOperationInputParameters(configurationBean
						.get("operation").get("name").textValue());
				for (TypeDescriptor descriptor : inputDescriptors) {
					inputPorts.add(descriptor.getName());
				}
			} catch (UnknownOperationException | IOException e) {
			}
			// Make sure the port name is unique
			endpointReferenceInputPortName = WSDLActivity.ENDPOINT_REFERENCE;
			int counter = 0;
			while (inputPorts.contains(endpointReferenceInputPortName)) {
				endpointReferenceInputPortName = WSDLActivity.ENDPOINT_REFERENCE + counter++;
			}
		}
		return endpointReferenceInputPortName;
	}

}
