package eu.dnetlib.enabling.datastructures;

import java.util.Map;

import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlRootElement;

import com.google.common.collect.Maps;

import eu.dnetlib.enabling.annotations.DnetResource;
import eu.dnetlib.enabling.annotations.IndexedField;
import eu.dnetlib.rmi.objects.is.DnetResourceFormat;
import eu.dnetlib.rmi.objects.is.DnetResourceKind;

@XmlRootElement
@DnetResource(type = "MetaWorkflow", kind = DnetResourceKind.UNIT, format = DnetResourceFormat.JSON)
public class MetaWorkflow extends AbstractJsonResource {

	@XmlEnum
	public enum Status {
		EXECUTABLE("Executable", "icon-ok"), WAIT_USER_SETTINGS("Waiting user settings", "icon-edit"), WAIT_SYS_SETTINGS("Waiting system settings",
				"icon-refresh"), ASSIGNED("Assigned", "icon-ok-circle"), MISSING("Missing workflow", "icon-warning-sign");

		public String displayName;
		public String icon;

		Status(final String displayName, final String icon) {
			this.displayName = displayName;
			this.icon = icon;
		}
	}

	@IndexedField(id = "family", label = "Family")
	private String family;

	@IndexedField(id = "section", label = "Section")
	private String section;

	@IndexedField(id = "datasource", label = "Datasource Id")
	private String datasourceId;
	private String datasourceName;
	private String email;
	private boolean scheduled = false;
	private String cronExpression;
	private int minInterval;

	@IndexedField(id = "metaWf::ifaceId", label = "Interface ID in MetaWf")
	private String datasourceInterfaceId;

	private Status status = Status.ASSIGNED;

	private Map<String, String> globalParams = Maps.newHashMap();

	private WorkflowInstance rootWorkflowInstance;

	private WorkflowInstance destroyWorkflowInstance;

	public MetaWorkflow() {}

	public MetaWorkflow(final String name, final String family, final String section) {
		setName(name);
		this.family = family;
		this.section = section;
	}

	public String getFamily() {
		return family;
	}

	public void setFamily(final String family) {
		this.family = family;
	}

	public String getSection() {
		return section;
	}

	public void setSection(final String section) {
		this.section = section;
	}

	public String getDatasourceId() {
		return datasourceId;
	}

	public void setDatasourceId(final String datasourceId) {
		this.datasourceId = datasourceId;
	}

	public String getDatasourceName() {
		return datasourceName;
	}

	public void setDatasourceName(final String datasourceName) {
		this.datasourceName = datasourceName;
	}

	public String getDatasourceInterfaceId() {
		return datasourceInterfaceId;
	}

	public void setDatasourceInterfaceId(final String datasourceInterfaceId) {
		this.datasourceInterfaceId = datasourceInterfaceId;
	}

	public Status getStatus() {
		return status;
	}

	public void setStatus(final Status status) {
		this.status = status;
	}

	public WorkflowInstance getRootWorkflowInstance() {
		return rootWorkflowInstance;
	}

	public void setRootWorkflowInstance(final WorkflowInstance rootWorkflowInstance) {
		this.rootWorkflowInstance = rootWorkflowInstance;
	}

	public Map<String, String> getGlobalParams() {
		return globalParams;
	}

	public void setGlobalParams(final Map<String, String> globalParams) {
		this.globalParams = globalParams;
	}

	public final String getEmail() {
		return email;
	}

	public final void setEmail(final String email) {
		this.email = email;
	}

	public final boolean isScheduled() {
		return scheduled;
	}

	public final void setScheduled(final boolean scheduled) {
		this.scheduled = scheduled;
	}

	public final String getCronExpression() {
		return cronExpression;
	}

	public final void setCronExpression(final String cronExpression) {
		this.cronExpression = cronExpression;
	}

	public final int getMinInterval() {
		return minInterval;
	}

	public final void setMinInterval(final int minInterval) {
		this.minInterval = minInterval;
	}

	public WorkflowInstance findWorkflowInstanceByName(final String name) {
		return findWorkflowInstanceByName(name, getRootWorkflowInstance());
	}

	private WorkflowInstance findWorkflowInstanceByName(final String name, final WorkflowInstance wi) {
		if (wi.getWfName().equals(name)) { return wi; }
		for (WorkflowInstance i : wi.getChildren()) {
			final WorkflowInstance res = findWorkflowInstanceByName(name, i);
			if (res != null) { return res; }
		}
		return null;
	}

	public final WorkflowInstance getDestroyWorkflowInstance() {
		return destroyWorkflowInstance;
	}

	public final void setDestroyWorkflowInstance(final WorkflowInstance destroyWorkflowInstance) {
		this.destroyWorkflowInstance = destroyWorkflowInstance;
	}

}
