package eu.dnetlib.msro.workflows.nodes.blackboard;

import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.googlecode.sarasvati.Arc;
import com.googlecode.sarasvati.Engine;
import com.googlecode.sarasvati.NodeToken;
import com.googlecode.sarasvati.env.Env;

import eu.dnetlib.enabling.tools.blackboard.AbstractBlackboardJobListener;
import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
import eu.dnetlib.msro.workflows.util.WorkflowsConstants;

public class BlackboardWorkflowJobListener extends AbstractBlackboardJobListener {

	/**
	 * logger.
	 */
	private static final Log log = LogFactory.getLog(BlackboardWorkflowJobListener.class);

	/**
	 * workflow engine.
	 */
	private Engine engine;

	/**
	 * workflow node token.
	 */
	private NodeToken token;

	@Override
	protected void onDone(final BlackboardJob job) {
		log.debug("Blackboard workflow node DONE");
		complete(job, Arc.DEFAULT_ARC);
	}

	public BlackboardWorkflowJobListener(final Engine engine, final NodeToken token) {
		super();
		this.engine = engine;
		this.token = token;
	}

	@Override
	final public void processJob(final BlackboardJob job) {
		token.getEnv().setTransientAttribute(WorkflowsConstants.BLACKBOARD_JOB, job);
		super.processJob(job);
	}

	@Override
	protected void onFailed(final BlackboardJob job) {
		log.warn("Blackboard workflow node FAILED: " + job.getError());
		token.getEnv().setAttribute(WorkflowsConstants.SYSTEM_HAS_FAILED, true);
		token.getEnv().setAttribute(WorkflowsConstants.SYSTEM_ERROR, job.getError());
		complete(job, "failed");
	}

	final protected void complete(final BlackboardJob job, final String arc) {
		final Env env = token.getEnv();

		populateEnv(env, job.getParameters());

		engine.complete(token, arc);
		engine.executeQueuedArcTokens(token.getProcess());
	}

	protected void populateEnv(final Env env, Map<String, String> responseParams) {
		for (Entry<String, String> entry : responseParams.entrySet()) {
			env.setAttribute(WorkflowsConstants.BLACKBOARD_PARAM_PREFIX + entry.getKey(), entry.getValue());
		}
	}

	@Override
	protected void onOngoing(final BlackboardJob job) {
		token.getEnv().setAttribute(WorkflowsConstants.BLACKBOARD_IS_GOING, true);
	}

	public Engine getEngine() {
		return engine;
	}

	public void setEngine(final Engine engine) {
		this.engine = engine;
	}

	public NodeToken getToken() {
		return token;
	}

	public void setToken(final NodeToken token) {
		this.token = token;
	}

}
