/**
 *
 */
package net.sf.taverna.t2.activities.interaction;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

import net.sf.taverna.t2.activities.interaction.atom.AtomUtils;
import net.sf.taverna.t2.activities.interaction.jetty.InteractionJetty;
import net.sf.taverna.t2.activities.interaction.preference.InteractionPreference;
import net.sf.taverna.t2.activities.interaction.velocity.InteractionVelocity;
import net.sf.taverna.t2.security.credentialmanager.CredentialManager;

import org.apache.abdera.Abdera;
import org.apache.abdera.i18n.text.Normalizer;
import org.apache.abdera.i18n.text.Sanitizer;
import org.apache.abdera.model.Element;
import org.apache.abdera.model.Entry;
import org.apache.abdera.parser.stax.FOMElement;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Logger;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;

public final class InteractionActivityRunnable implements Runnable {

	private static final Logger logger = Logger
			.getLogger(InteractionActivityRunnable.class);

	private static final Abdera ABDERA = Abdera.getInstance();

	private final Template presentationTemplate;

	private final InteractionRequestor requestor;

	private CredentialManager credentialManager;

	private InteractionRecorder interactionRecorder;
	
	private InteractionUtils interactionUtils;

	private InteractionJetty interactionJetty;

	private InteractionPreference interactionPreference;

	private ResponseFeedListener responseFeedListener;

	private InteractionVelocity interactionVelocity;

	public InteractionActivityRunnable(final InteractionRequestor requestor,
			final Template presentationTemplate,
			final CredentialManager credentialManager,
			final InteractionRecorder interactionRecorder,
			final InteractionUtils interactionUtils,
			final InteractionJetty interactionJetty,
			final InteractionPreference interactionPreference,
			final ResponseFeedListener responseFeedListener,
			final InteractionVelocity interactionVelocity) {
		this.requestor = requestor;
		this.presentationTemplate = presentationTemplate;
		this.credentialManager = credentialManager;
		this.interactionRecorder = interactionRecorder;
		this.interactionUtils = interactionUtils;
		this.interactionJetty = interactionJetty;
		this.interactionPreference = interactionPreference;
		this.responseFeedListener = responseFeedListener;
		this.interactionVelocity = interactionVelocity;
	}

	@Override
	public void run() {
		/*
		 * InvocationContext context = callback.getContext();
		 */
		final String runId = InteractionUtils.getUsedRunId(this.requestor
				.getRunId());

		final String id = Sanitizer.sanitize(UUID.randomUUID().toString(), "",
				true, Normalizer.Form.D);

		final Map<String, Object> inputData = this.requestor.getInputData();

		if (interactionPreference.getUseJetty()) {
			interactionJetty.startJettyIfNecessary(credentialManager);
		}
		interactionJetty.startListenersIfNecessary();
		try {
			interactionUtils.copyFixedFile("pmrpc.js");
			interactionUtils.copyFixedFile("interaction.css");
		} catch (final IOException e1) {
			logger.error(e1);
			this.requestor.fail("Unable to copy necessary fixed file");
			return;
		}
		synchronized (ABDERA) {
			final Entry interactionNotificationMessage = this
					.createBasicInteractionMessage(id, runId);

			for (final String key : inputData.keySet()) {
				final Object value = inputData.get(key);
				if (value instanceof byte[]) {
					final String replacementUrl = interactionPreference
							.getPublicationUrlString(id, key);
					final ByteArrayInputStream bais = new ByteArrayInputStream(
							(byte[]) value);
					try {
						interactionUtils.publishFile(replacementUrl, bais,
								runId, id);
						bais.close();
						inputData.put(key, replacementUrl);
					} catch (final IOException e) {
						logger.error(e);
						this.requestor.fail("Unable to publish to " + replacementUrl);
						return;
					}
				}
			}

			final String inputDataString = this.createInputDataJson(inputData);
			if (inputDataString == null) {
				return;
			}
			final String inputDataUrl = interactionPreference
					.getInputDataUrlString(id);
			try {
				interactionUtils.publishFile(inputDataUrl, inputDataString,
						runId, id);
			} catch (final IOException e) {
				logger.error(e);
				this.requestor.fail("Unable to publish to " + inputDataUrl);
				return;
			}

			String outputDataUrl = null;

			if (!this.requestor.getInteractionType().equals(
					InteractionType.Notification)) {
				outputDataUrl = interactionPreference
						.getOutputDataUrlString(id);
			}
			final String interactionUrlString = this.generateHtml(inputDataUrl,
					outputDataUrl, inputData, runId, id);

			try {
				this.postInteractionMessage(id, interactionNotificationMessage,
						interactionUrlString, runId);
			} catch (IOException e) {
				logger.error(e);
				this.requestor.fail("Unable to post message");
				return;
			}
			if (!this.requestor.getInteractionType().equals(
					InteractionType.Notification)) {
				responseFeedListener.registerInteraction(
						interactionNotificationMessage, this.requestor);
			} else {
				this.requestor.carryOn();

			}
		}
	}

	private String createInputDataJson(final Map<String, Object> inputData) {
		try {
			return InteractionUtils.objectToJson(inputData);
		} catch (final IOException e) {
			logger.error(e);
			this.requestor.fail("Unable to generate JSON");
		}
		return null;
	}

	private Entry createBasicInteractionMessage(final String id,
			final String runId) {
		final Entry interactionNotificationMessage = ABDERA.newEntry();

		interactionNotificationMessage.setId(id);
		final Date timestamp = new Date();
		interactionNotificationMessage.setPublished(timestamp);
		interactionNotificationMessage.setUpdated(timestamp);

		interactionNotificationMessage.addAuthor("Taverna");
		interactionNotificationMessage.setTitle("Interaction from Taverna for "
				+ this.requestor.generateId());

		final Element runIdElement = interactionNotificationMessage
				.addExtension(AtomUtils.getRunIdQName());
		runIdElement.setText(StringEscapeUtils.escapeJavaScript(runId));
		
		final Element pathIdElement = interactionNotificationMessage.addExtension(AtomUtils.getPathIdQName());
		pathIdElement.setText(StringEscapeUtils.escapeJavaScript(this.requestor.getPath()));
		
		final Element countElement = interactionNotificationMessage.addExtension(AtomUtils.getCountQName());
		countElement.setText(StringEscapeUtils.escapeJavaScript(this.requestor.getInvocationCount().toString()));
		
		if (this.requestor.getInteractionType().equals(
				InteractionType.Notification)) {
			interactionNotificationMessage.addExtension(AtomUtils
					.getProgressQName());
		}
		final Element idElement = interactionNotificationMessage
				.addExtension(AtomUtils.getIdQName());
		idElement.setText(id);

		return interactionNotificationMessage;
	}

	private void postInteractionMessage(final String id, final Entry entry,
			final String interactionUrlString, final String runId) throws IOException {

		entry.addLink(StringEscapeUtils.escapeXml(interactionUrlString),
				"presentation");
		entry.setContentAsXhtml("<p><a href=\""
				+ StringEscapeUtils.escapeXml(interactionUrlString)
				+ "\">Open: "
				+ StringEscapeUtils.escapeXml(interactionUrlString)
				+ "</a></p>");

		URL feedUrl;

			feedUrl = new URL(interactionPreference
					.getFeedUrlString());
			final String entryContent = ((FOMElement) entry)
					.toFormattedString();
			final HttpURLConnection httpCon = (HttpURLConnection) feedUrl
					.openConnection();
			httpCon.setDoOutput(true);
			httpCon.setRequestProperty("Content-Type",
					"application/atom+xml;type=entry;charset=UTF-8");
			httpCon.setRequestProperty("Content-Length",
					"" + entryContent.length());
			httpCon.setRequestProperty("Slug", id);
			httpCon.setRequestMethod("POST");
			httpCon.setConnectTimeout(5000);
			final OutputStream outputStream = httpCon.getOutputStream();
			IOUtils.write(entryContent, outputStream, "UTF-8");
			outputStream.close();
			final int response = httpCon.getResponseCode();
			if ((response < 0) || (response >= 400)) {
				logger.error("Received response code" + response);
				throw (new IOException ("Received response code " + response));
			}
			if (response == HttpURLConnection.HTTP_CREATED) {
				interactionRecorder.addResource(runId, id,
						httpCon.getHeaderField("Location"));
			}
	}

	String generateHtml(final String inputDataUrl, final String outputDataUrl,
			final Map<String, Object> inputData, final String runId,
			final String id) {

		final VelocityContext velocityContext = new VelocityContext();

		for (final String inputName : inputData.keySet()) {
			final Object input = inputData.get(inputName);
			velocityContext.put(inputName, input);
		}

		velocityContext.put("feed", interactionPreference
				.getFeedUrlString());
		velocityContext.put("runId", runId);
		velocityContext.put("entryId", id);
		final String pmrpcUrl = interactionPreference
				.getLocationUrl() + "/pmrpc.js";
		velocityContext.put("pmrpcUrl", pmrpcUrl);
		velocityContext.put("inputDataUrl", inputDataUrl);
		velocityContext.put("outputDataUrl", outputDataUrl);
		final String interactionUrl = interactionPreference
				.getInteractionUrlString(id);

		velocityContext.put("interactionUrl", interactionUrl);

		String presentationUrl = "";
		final String authorizeUrl = "";
		try {
			if (this.requestor.getPresentationType().equals(
					InteractionActivityType.VelocityTemplate)) {

				presentationUrl = interactionPreference
						.getPresentationUrlString(id);

				final String presentationString = this.processTemplate(
						this.presentationTemplate, velocityContext);
				interactionUtils.publishFile(presentationUrl,
						presentationString, runId, id);

			} else if (this.requestor.getPresentationType().equals(
					InteractionActivityType.LocallyPresentedHtml)) {
				presentationUrl = this.requestor.getPresentationOrigin();
			}

			velocityContext.put("presentationUrl", presentationUrl);

			final String interactionString = this.processTemplate(
					interactionVelocity.getInteractionTemplate(),
					velocityContext);
			interactionUtils.publishFile(interactionUrl, interactionString,
					runId, id);

			if (!authorizeUrl.isEmpty()) {
				return authorizeUrl;
			}
			return interactionUrl;
		} catch (final IOException e) {
			logger.error(e);
			this.requestor.fail("Unable to generate HTML");
			return null;
		}
	}

	private String processTemplate(final Template template,
			final VelocityContext context) throws IOException {
		final StringWriter resultWriter = new StringWriter();
		template.merge(context, resultWriter);
		resultWriter.close();
		return resultWriter.toString();
	}

}