package gov.va.vinci.dart.biz;

import gov.va.vinci.dart.common.exception.ObjectNotFoundException;
import gov.va.vinci.dart.service.DartObjectFactory;

import java.util.List;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@SuppressWarnings("rawtypes")
@Entity
@Table(name="workflowtemplate", schema="hib")
public class WorkflowTemplate extends ReferenceObject implements Comparable {

	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="groupid")
	Group reviewer;

	@Column(name="workflowtypeid")
	protected int workflowTypeId;

	@ManyToMany(fetch=FetchType.LAZY)
	@JoinTable(
		      name="datasourceworkflowtemplate", schema="hib",
		      joinColumns={@JoinColumn(name="workflowtemplateid", referencedColumnName="ID")},
		      inverseJoinColumns={@JoinColumn(name="datasourceid", referencedColumnName="ID")})
	Set<DataSource> dataSources;
	
	@ManyToMany(fetch=FetchType.LAZY)
	@JoinTable(
		      name="documenttemplateworkflowtemplate", schema="hib",
		      joinColumns={@JoinColumn(name="workflowtemplateid", referencedColumnName="ID")},
		      inverseJoinColumns={@JoinColumn(name="documenttemplateid", referencedColumnName="ID")})
	Set<DocumentTemplate> documentTemplates;	//lock/unlock
	
	@ManyToMany(fetch=FetchType.LAZY)
	@JoinTable(
		      name="showdocumenttemplateworkflowtemplate", schema="hib",
		      joinColumns={@JoinColumn(name="workflowtemplateid", referencedColumnName="ID")},
		      inverseJoinColumns={@JoinColumn(name="documenttemplateid", referencedColumnName="ID")})
	Set<DocumentTemplate> documentTemplatesToShowIndependent;

	
	public Group getReviewer() {
		return reviewer;
	}
	
	public void setReviewer(final Group reviewer) {
		this.reviewer = reviewer;
	}

	public void setWorkflowTypeId(int workflowTypeId) {
		this.workflowTypeId = workflowTypeId;
	}

	public int getWorkflowTypeId() {
		return workflowTypeId;
	}

	public Set<DataSource> getDataSources() {
		return dataSources;
	}

	public Set<DocumentTemplate> getDocumentTemplates() {
		return documentTemplates;
	}
	
	public Set<DocumentTemplate> getDocumentTemplatesToShowIndependent() {
		return documentTemplatesToShowIndependent;
	}

	
	public static WorkflowTemplate findById(int workflowTemplateId) throws ObjectNotFoundException {
		return DartObjectFactory.getInstance().getWorkflowTemplateDAO().findById(workflowTemplateId);
	}
	

//	public static WorkflowTemplate findByGroupId(int groupId) throws ObjectNotFoundException {
//		return DartObjectFactory.getInstance().getWorkflowTemplateDAO().findByGroupId(groupId);
//	}	

	public static WorkflowTemplate findByGroupIdAndWorkflowTypeId(final int groupId, final int workflowTypeId) throws ObjectNotFoundException {
		return DartObjectFactory.getInstance().getWorkflowTemplateDAO().findByGroupIdAndWorkflowTypeId(groupId, workflowTypeId);
	}	
	
	public static List<WorkflowTemplate> listAll() {
		return DartObjectFactory.getInstance().getWorkflowTemplateDAO().listAll();
	}

	public static List<WorkflowTemplate> listByWorkflowTypeId(final int workflowTypeId) {
		return DartObjectFactory.getInstance().getWorkflowTemplateDAO().listByWorkflowTypeId(workflowTypeId);
	}

	
	/**
	 * Returns the workflow status display name, used in the UI
	 * @return
	 */
	public String getStatusDisplayName() {
		String name = getName();

		if( getReviewer() != null ) {
			return (getReviewer().getStatusDisplayName());
		}

		return name;
	}

	
	@Override 
	public boolean equals(Object obj) {
		if( obj == null ) {
			return false;
		}

//		if( (WorkflowTemplate.class.isAssignableFrom(obj.getClass())) == false &&
//			 (obj.getClass().isAssignableFrom(WorkflowTemplate.class)) == false ) {
		if ((obj instanceof WorkflowTemplate) == false) {
			return false;
		}

		return this.getId() == ((WorkflowTemplate)obj).getId();	//compare the id column for the WorkflowTemplate
	}

	@Override
	public int compareTo(Object o) {
		if (o == null) {
			return -1;
		}
		if ((o instanceof WorkflowTemplate) == false) {
			return -1;
		}
		
		WorkflowTemplate obj2 = (WorkflowTemplate)o;

		// sort by id column for the WorkflowTemplate
		if (this.getId() == obj2.getId()) {
			return 0;
		}
		
		return this.getId() < obj2.getId() ? -1 : 1;
	}
	
}
