/********************************************************************
 * Copyright © 2004 VHA. All rights reserved
 ********************************************************************/
package gov.va.med.esr.service;

import java.util.List;

import gov.va.med.fw.model.EntityKey;
import gov.va.med.fw.security.UserPrincipal;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.service.pagination.PaginatedSearchService;
import gov.va.med.fw.service.pagination.SearchQueryInfo;

import gov.va.med.esr.common.model.cases.WorkflowCase;
import gov.va.med.esr.common.model.lookup.FunctionalGroup;
import gov.va.med.esr.common.model.lookup.WkfCaseType;
import gov.va.med.esr.common.model.lookup.WkfIssueType;
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.id.PersonEntityKey;
import gov.va.med.esr.common.model.workload.WorkflowCaseInfo;
import gov.va.med.esr.common.clock.Clock.Type;

public interface WorkflowService extends PaginatedSearchService{
    /**
     * Create a new Work flow Case
     * @param workflowCase
     * @return
     * @throws ServiceException
     */
    public WorkflowCase create(WorkflowCase workflowCase) throws ServiceException;
    
    /**
     * Creates workflow case with given type and error message for UI (Manage)
     * @param person
     * @param groupType
     * @param wkfCaseType
     * @param wkfIssueType
     * @param errorMessage
     * @throws ServiceException
     */
    public void autoCreateCase(Person person, FunctionalGroup groupType, 
    		WkfCaseType wkfCaseType, WkfIssueType wkfIssueType, String errorMessage) throws ServiceException;

    /**
     * Auto create case from triggers with case info
     * @param workflowCaseInfo
     * @throws ServiceException
     */
    public void autoCreateCase(WorkflowCaseInfo workflowCaseInfo) throws ServiceException;
    
    /**
     * Update an existing workflow case (reassign, close)
     * @param workflowCase
     * @return
     * @throws ServiceException
     */
    public WorkflowCase update(WorkflowCase workflowCase) throws ServiceException;
    
    public WorkflowCase updateWorkItem(WorkflowCase workflowCase) throws ServiceException;
    
    /**
     * Close the list of cases identified by case ids
     * @param caseIds
     * @return
     * @throws ServiceException
     */
    public void close(List caseIds) throws ServiceException;
    
    /**
     * Close workflow case
     * @param workflowCase
     * @throws ServiceException
     */
    public void close(WorkflowCase workflowCase) throws ServiceException;
    
    /**
     * Assign the list of cases identified by case ids
     * @param caseIds
     * @param user
     * @return
     * @throws ServiceException
     */
    public void assign(List caseIds, UserPrincipal assignedBy, UserPrincipal assinedTo) throws ServiceException;
    
    /**
     * Cross functional group assignment
     * @param caseIds
     * @param assignedBy
     * @param assinedTo
     * @throws ServiceException
     */
    public void assign(List caseIds, UserPrincipal assignedBy, UserPrincipal assinedTo, 
            FunctionalGroup toGroup) throws ServiceException;
    
    /**
     * Search for work flow cases
     * @param searchCriteria
     * @return
     * @throws ServiceException
     */
    public List search(SearchQueryInfo searchCriteria) throws ServiceException;
    
    /**
     * Find the workflow case by entity id (identifier)
     * @param entityKey
     * @return
     * @throws ServiceException
     */
    public WorkflowCase find(EntityKey entityKey) throws ServiceException;

    /**
     * Finds an open workflow case for the person of the specified type 
     * If a case is not found, creates a new case if create is true
     * @param person
     * @param wkfCaseType
     * @param create
     * @return
     * @throws ServiceException
     */
    public WorkflowCase getWorkItem(Person person, WkfCaseType wkfCaseType, boolean create ) throws ServiceException;
    
    /**
     * @param person
     * @return
     * @throws ServiceException
     */
    public WorkflowCase getMostRecentWorkflowItem(Person person) throws ServiceException;

    /**
     * Get Open cases count for Veteran
     * @param personEntityKey
     * @return
     * @throws ServiceException
     */
    
    public int getOpenCasesCount(PersonEntityKey personEntityKey) throws ServiceException;
    /**
     * Get workitems summary for user
     * @param user
     * @return
     * @throws ServiceException
     */
    public WorkItemsSummary getWorkItemsSummaryForUser(UserPrincipal user) throws ServiceException;    
    
    /**
     * Process Workflow event due to clock expiring.
     * 
     * @param person
     * @param clock
     * @throws ServiceException
     */
    public void processWorkflowEvent(Person person, Type clock) throws ServiceException;
    
    /**
     * 
     * @param person
     * @param wkfCaseType
     * @return
     * @throws ServiceException
     */
    public List<WorkflowCase> getOpenWorkItemLst(Person person, WkfCaseType wkfCaseType) throws ServiceException;
}
