package gov.va.med.esr.service;

// Java Classes
import java.util.List;

// Framework Classes
import gov.va.med.fw.model.EntityKey;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.service.pagination.PaginatedSearchService;
import gov.va.med.fw.service.pagination.SearchQueryInfo;

// ESR Classes
import gov.va.med.esr.common.model.person.Person;
import gov.va.med.esr.common.model.person.PersonMergeInfo;
import gov.va.med.esr.common.model.person.id.PersonEntityKey;
import gov.va.med.esr.common.model.person.id.PersonIdEntityKey;
import gov.va.med.esr.common.model.person.id.VPIDEntityKey;

/**
 * Business service interface for person merge.
 * @author DNS   CHENB
 * @author Andrew Pach
 */
public interface PersonMergeService extends PaginatedSearchService
{
	/**
	 * Get the PersonMergeInfo for given key.
     *
	 * @param personMergeInfoEntityKey the person merge info entity key.
	 * @return The person merge info for the passed in entity key.
	 * @throws ServiceException if an problems were encountered.
	 */
	public PersonMergeInfo getPersonMergeInfo(EntityKey personMergeInfoEntityKey) throws ServiceException;

	/**
	 * Gets PersonMergeInfo based on the person entity key of the "primary" person.
     *
	 * @param primaryPersonIdEntityKey The primary person's entity key.
	 * @return The person merge info associated with the primary person entity key.
     * @throws ServiceException if an problems were encountered.
	 */
    public PersonMergeInfo getPersonMergeDataInfo(PersonIdEntityKey primaryPersonIdEntityKey) throws ServiceException;

    /**
     * Gets PersonMergeInfo based on the person entity key of the "primary" person.
     *
     * @param primaryPersonIdEntityKey The primary person's entity key.
     * @return The person merge info associated with the primary person entity key.
     * @throws ServiceException if an problems were encountered.
     */
	public PersonMergeInfo getPersonMergeInfo(PersonIdEntityKey primaryPersonIdEntityKey) throws ServiceException;

	
	public boolean hasActiveMerge(PersonIdEntityKey primaryPersonIdEntityKey) throws ServiceException;
	
	/**
	 * Update person merge information.
     *
	 * @param info The person merge info.
	 * @return The updated person merge info.
     * @throws ServiceException if an problems were encountered.
	 */
	public PersonMergeInfo updatePersonMergeInfo(PersonMergeInfo info) throws ServiceException;

	/**
	 * Update person merge information by primary and deprecated person ids
	 *
	 * @param primaryId Primary Person ID.
	 * @param deprecatedId Deprecated Person ID.
	 * @return The updated person merge info.
	 * @throws ServiceException if an problems were encountered.
	 */
	public PersonMergeInfo updatePersonMergeInfoByPrimaryDepIDs(PersonEntityKey primaryId, PersonEntityKey deprecatedId) throws ServiceException;
	   
    /**
     * Save merge information in progress.  This method will ensure the entity has changed.
     *
     * @param info The person merge info.
     * @return The updated person merge info.
     * @throws ServiceException if an problems were encountered.
     */
    public PersonMergeInfo saveInProgress(PersonMergeInfo info) throws ServiceException;

    /**
     * Process and store PeronMerge request from external.
     * If there is a record in Person_Merge with same Primary and Deprecated Id's, then do nothing.
	 * If there is a record in Person_Merge with fliped Primary and Deprecated Id's,
     * then replace it with new mergeInfo.
	 * If there is a record in Person_Unmerge for both PersonIds, then remove it from Person_Unmerge
     * and store the new merge_info.
	 * @param info The person merge info
	 * @throws ServiceException if an problems were encountered.
	 */
    public void processPersonMergeInfo(PersonMergeInfo info, VPIDEntityKey deprecatedVPID, VPIDEntityKey survivingVPID) throws ServiceException;

	/**
	 * Deletes a person merge info record or when an unmerge request from PSIM while this has not been merged.
	 * @param info the person mege info
     * @throws ServiceException if an problems were encountered.
	 */
	public void deletePersonMergeInfo(PersonMergeInfo info) throws ServiceException;

	/**
	 * Update the primary person (when a person merge is complete).
	 * @param incoming The incoming person to update
     * @return the updated person
     * @throws ServiceException if an problems were encountered.
	 */
	public Person updatePerson(Person incoming) throws ServiceException;

    /**
     * Searches and returns a list of PersonMergeInfo objects.
     *
     * @param searchQueryInfo The search criteria
     *
     * @return The list of PersonMergeInfo objects
     * @throws ServiceException if any problems were encountered.
     */
    public List search(SearchQueryInfo searchQueryInfo) throws ServiceException;
    
    
	public boolean hasDeprecatedRecord(PersonIdEntityKey deprecatedPersonIdEntityKey) throws ServiceException ;
}
