package gov.va.vinci.dart.biz;

import java.util.Date;
import java.util.List;

import gov.va.vinci.dart.common.ValidationHelper;
import gov.va.vinci.dart.common.exception.ValidationException;
import gov.va.vinci.dart.service.DartObjectFactory;

import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name="Task",schema="hib")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
	    name="tasktypeid",
	    discriminatorType=DiscriminatorType.INTEGER
	)
@DiscriminatorValue("1")
public abstract class Task extends BusinessObject {
	
	@ManyToOne
	@JoinColumn(name="requestid")
	Request request;
	
	@ManyToOne
	@JoinColumn(name="reviewid")
	Review review;

	@ManyToOne
	@JoinColumn(name="workflowid")
	protected RequestWorkflow workflow;
	
	@Temporal(TemporalType.TIMESTAMP)
	@Column(name="completedon")
	protected Date completedOn;

	
	public Request getRequest() {
		return request; 
	}

	public Review getReview() {
		return review;
	}

	public void setReview(Review review) {
		this.review = review;
	}

	public RequestWorkflow getWorkflow() {
		return workflow;
	}
	
	public Date getCompletedOn() {
		return completedOn;
	}

	public static Task findById(final int taskId) {
		return DartObjectFactory.getInstance().getTaskDAO().findById(taskId);
	}
	
	public static List<Task> listByRequest(final int requestId) {
		return DartObjectFactory.getInstance().getTaskDAO().listByRequestId(requestId);
	}

	public static List<Task> listOpenByRequest(final int requestId) {
		return DartObjectFactory.getInstance().getTaskDAO().listOpenByRequestId(requestId);
	}

	public static List<Task> listOpenByWorkflowAndRequest(final int workflowId, final int requestId) {
		return DartObjectFactory.getInstance().getTaskDAO().listOpenByWorkflowAndRequestId(workflowId, requestId);
	}
	
	
	public static List<Task> listAll() {
		return DartObjectFactory.getInstance().getTaskDAO().listAll();
	}
	
	public static TaskAging getTaskAging(final int ownerId) {
		return DartObjectFactory.getInstance().getPersonTaskDAO().getTaskAging(ownerId);
	}
	
	protected Task() {}
	
	public void modify(final RequestWorkflow workflow, final Request request, final String name, final String updatedby) throws ValidationException {

		validateModify(request, name, updatedby);
		
		this.request = request;
		
		//check for a null workflow object here before setting it (new request vs. old request)		
		if( workflow != null ) {
			this.workflow = workflow;
		}//end if
		
		this.name = name;
		this.updatedBy = updatedby;
		this.updatedOn = new Date();
	}
	
	private void validateModify(final Request request, final String name, final String updatedby) throws ValidationException {
		ValidationHelper.required("Request", request);
		ValidationHelper.required("Name", name);
		ValidationHelper.validateSize("Name", name, 1, 64);
		ValidationHelper.required("Updated By", updatedby);
		ValidationHelper.validateSize("Updated By", updatedby, 1, 32);
		
		// TODO- how about a validation that the owner must be a activity participant or something like that? 
	}
	
	public void complete(final String updatedBy) {
		if (this.completedOn == null) {
			this.completedOn = new Date();
			this.updatedOn = new Date();
			this.updatedBy = updatedBy;
		}
	}
	
	public void delete() {
		DartObjectFactory.getInstance().getTaskDAO().delete(this);
	}
}
