package net.sf.taverna.t2.activities.xpath;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.taverna.t2.invocation.InvocationContext;
import net.sf.taverna.t2.reference.ErrorDocumentService;
import net.sf.taverna.t2.reference.ReferenceService;
import net.sf.taverna.t2.reference.T2Reference;
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.AsynchronousActivityCallback;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.InvalidXPathException;
import org.dom4j.Node;
import org.dom4j.XPath;
import org.dom4j.XPathException;

import com.fasterxml.jackson.databind.JsonNode;

/**
 * Enhanced XPath activity.
 *
 * @author Sergejs Aleksejevs
 */
public class XPathActivity extends AbstractAsynchronousActivity<JsonNode> {

	public static final String URI = "http://ns.taverna.org.uk/2010/activity/xpath";

	// These ports are default ones (and only ones - XPath activity will not have dynamic ports)
	public static final String IN_XML = "xml_text";
	public static final String OUT_TEXT = "nodelist";
	public static final String OUT_XML = "nodelistAsXML";

	private static final String SINGLE_VALUE_TEXT = "firstNode";
	private static final String SINGLE_VALUE_XML = "firstNodeAsXML";
	
	// Configuration bean for this activity - essentially defines a particular instance
	// of the activity through the values of its parameters
	private JsonNode json;

	@Override
	public JsonNode getConfiguration() {
		return this.json;
	}

	@Override
	public void configure(JsonNode json) throws ActivityConfigurationException {
		// Check configBean is valid
		if (!XPathUtils.isValid(json)) {
			throw new ActivityConfigurationException("Invalid configuration of XPath activity...");
			// TODO - check this
		}

		// Store for getConfiguration()
		this.json = json;
	}

	protected void configurePorts() {
		// ---- REMOVE OLD PORTS ----
	  
		// In case we are being reconfigured - remove existing ports first to avoid duplicates
		removeInputs();
		removeOutputs();

		// ---- CREATE NEW INPUTS AND OUTPUTS ----
		
		// all ports in this activity are static, so no dependency on the values in config bean
		
		// single input port: the input XML text will be treated as String for now
		addInput(IN_XML, 0, true, null, String.class);

		addOutput(SINGLE_VALUE_TEXT, 0);
		addOutput(SINGLE_VALUE_XML, 0);
		addOutput(OUT_TEXT, 1);
		addOutput(OUT_XML, 1);
	}

	/**
	 * This method executes pre-configured instance of XPath activity.
	 */
	@Override
	public void executeAsynch(final Map<String, T2Reference> inputs,
			final AsynchronousActivityCallback callback) {
		// Don't execute service directly now, request to be run asynchronously
		callback.requestRun(new Runnable() {
			@Override
			@SuppressWarnings("unchecked")
			public void run() {

				InvocationContext context = callback.getContext();
				ReferenceService referenceService = context.getReferenceService();

				// ---- RESOLVE INPUT ----

				String xmlInput = (String) referenceService.renderIdentifier(inputs.get(IN_XML),
						String.class, context);

				// ---- DO THE ACTUAL SERVICE INVOCATION ----

				List<Node> matchingNodes = new ArrayList<Node>();

				// only attempt to execute XPath expression if there is some input data
				if (xmlInput != null && xmlInput.length() > 0) {
					// XPath configuration is taken from the config bean
					try {
						XPath expr = DocumentHelper.createXPath(json.get("xpathExpression").textValue());
						Map<String, String> xpathNamespaceMap = new HashMap<>();
						for (JsonNode namespaceMapping : json.get("xpathNamespaceMap")) {
							xpathNamespaceMap.put(namespaceMapping.get("prefix").textValue(),
									namespaceMapping.get("uri").textValue());
						}
						expr.setNamespaceURIs(xpathNamespaceMap);
						Document doc = DocumentHelper.parseText(xmlInput);
						matchingNodes = expr.selectNodes(doc);
					} catch (InvalidXPathException e) {
						callback.fail("Incorrect XPath Expression -- XPath processing library "
								+ "reported the following error: " + e.getMessage(), e);

						// make sure we don't call callback.receiveResult later
						return;
					} catch (DocumentException e) {
						callback.fail("XML document was not valid -- XPath processing library "
								+ "reported the following error: " + e.getMessage(), e);

						// make sure we don't call callback.receiveResult later
						return;
					} catch (XPathException e) {
						callback.fail(
								"Unexpected error has occurred while executing the XPath expression. "
										+ "-- XPath processing library reported the following error:\n"
										+ e.getMessage(), e);

						// make sure we don't call callback.receiveResult later
						return;
					}
				}
				
				// --- PREPARE OUTPUTS ---

				List<String> outNodesText = new ArrayList<String>();
				List<String> outNodesXML = new ArrayList<String>();
				Object textValue = null;
				Object xmlValue = null;

				for (Object o : matchingNodes) {
					if (o instanceof Node) {
						Node n = (Node) o;
						if (n.getStringValue() != null
								&& n.getStringValue().length() > 0) {
							outNodesText.add(n.getStringValue());
							if (textValue == null)
								textValue = n.getStringValue();
						}
						outNodesXML.add(n.asXML());
						if (xmlValue == null)
							xmlValue = n.asXML();
					} else {
						outNodesText.add(o.toString());
						if (textValue == null)
							textValue = o.toString();
					}
				}

				// ---- REGISTER OUTPUTS ----

				Map<String, T2Reference> outputs = new HashMap<String, T2Reference>();
				if (textValue == null) {
					ErrorDocumentService errorDocService = referenceService
							.getErrorDocumentService();
					textValue = errorDocService.registerError(
							"No value produced", 0, callback.getContext());
				}

				if (xmlValue == null) {
					ErrorDocumentService errorDocService = referenceService
							.getErrorDocumentService();
					xmlValue = errorDocService.registerError(
							"No value produced", 0, callback.getContext());
				}

				T2Reference firstNodeAsText = referenceService.register(
						textValue, 0, true, context);
				outputs.put(SINGLE_VALUE_TEXT, firstNodeAsText);

				T2Reference firstNodeAsXml = referenceService.register(
						xmlValue, 0, true, context);
				outputs.put(SINGLE_VALUE_XML, firstNodeAsXml);

				T2Reference outNodesAsText = referenceService.register(
						outNodesText, 1, true, context);
				outputs.put(OUT_TEXT, outNodesAsText);

				T2Reference outNodesAsXML = referenceService.register(
						outNodesXML, 1, true, context);
				outputs.put(OUT_XML, outNodesAsXML);

				// return map of output data, with empty index array as this is
				// the only and final result (this index parameter is used if
				// pipelining output)
				callback.receiveResult(outputs, new int[0]);
			}
		});
	}

}
