package gov.va.vinci.dart.wf2;

import java.util.List;

import gov.va.vinci.dart.common.exception.ValidationException;
import gov.va.vinci.dart.biz.Request;
import gov.va.vinci.dart.biz.Review;
import gov.va.vinci.dart.biz.RequestWorkflow;
import gov.va.vinci.dart.json.ReviewStatusListView;

/** A workflow.
 * 
 */
public interface Workflow {

	public static final int WF_OPERATION_ENTRY = 0;  // when a state is entered
	public static final int WF_OPERATION_INITIALIZE = 1;
	public static final int WF_OPERATION_SUBMIT = 2;
	public static final int WF_OPERATION_APPROVE = 3;
	public static final int WF_OPERATION_DENY = 4;
	public static final int WF_OPERATION_CHANGE_REQUEST = 5;
	public static final int WF_OPERATION_CLOSE = 6;
	
	/** Handle the initialize event.
	 * 
	 * @param request
	 * @param userLoginId
	 * @throws WorkflowException
	 */
	void initialize(final RequestWorkflow workflow, final Request request, final String userLoginId) throws WorkflowException;
	
	/** Handle the submit event.
	 * 
	 * @param request
	 * @param userLoginId
	 * @throws WorkflowException
	 */
	void submit(final RequestWorkflow workflow, final Request request, final String userLoginId) throws WorkflowException;
	
	/** Handle the approve event.
	 * 
	 * @param request
	 * @param userLoginId
	 * @throws WorkflowException
	 */
	void approve(final RequestWorkflow workflow, final Review review, final Request request, final String userLoginId) throws WorkflowException;
	
	/** Handle the deny event.
	 * 
	 * @param request
	 * @param userLoginId
	 * @throws WorkflowException
	 */
	void deny(final RequestWorkflow workflow, final Review review, final Request request, final String userLoginId) throws WorkflowException;
	
	/** Handle the change request event.
	 * 
	 * @param request
	 * @param userLoginId
	 * @throws WorkflowException
	 */
	void changeRequest(final RequestWorkflow workflow, final Review review, final Request request, final String userLoginId) throws WorkflowException;
	
	/** Handle the close event.
	 * 
	 * @param request
	 * @param userLoginId
	 * @throws WorkflowException
	 */
	void close(final Review review, final Request request, final String userLoginId) throws WorkflowException;
	
	/** Get the final state of the workflow item.
	 * 
	 * @return
	 */
	int getFinalState();

	/**
	 * Get the state of the final review (final NDS review)
	 * @return
	 */
	int getFinalReviewState();

	/**
	 * Get the state of the request when submitted.
	 * @return
	 */
	int getSubmittedState();
	
	
	/** Calculate the percentage of review completion on the request.
	 * 
	 * @return
	 */
	String calculateReviewCompletion( final RequestWorkflow workflow, final Request request );
	
	/**
	 * Returns true if ready for the initial review, based on workflow state
	 * @return
	 */
	boolean isReadyForInitialReview( final RequestWorkflow workflow, final Request request );

	/**
	 * Returns true if the initial review is completed, based on workflow state
	 * @return
	 */
	boolean isInitialReviewCompleted( final RequestWorkflow workflow, final Request request );
	
	/**
	 * Returns true if ready for the final review, based on workflow state
	 * @return
	 */
	boolean isReadyForFinalReview( final RequestWorkflow workflow, final Request request );

	/**
	 * Returns true if the final review has been completed, based on workflow state
	 * @return
	 */
	boolean isFinalReviewCompleted( final RequestWorkflow workflow, final Request request );
	
    /**
     * Checks if is ready for group review.
     *
     * @param workflow the workflow
     * @param request the request
     * @return true, if is ready for group review
     */
    boolean isReadyForGroupReview(RequestWorkflow workflow, Request request);
	
	/**
	 * Retrieves the list of ReviewStatusView details for the specified workflow (used for the Median Wait Time display).
	 * 
	 * @param workflow
	 * @param request
	 * @param result
	 */
	void populateReviewStatusList( final RequestWorkflow workflow, final Request request, ReviewStatusListView result );

}
