/********************************************************************
 * Copyright © 2012 VHA. All rights reserved
 ********************************************************************/

package gov.va.med.esr.common.batchprocess;

import gov.va.med.esr.common.model.CommonEntityKeyFactory;
import gov.va.med.esr.common.model.party.Email;
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.persistent.demographic.EmailDAO;
import gov.va.med.esr.service.trigger.PersonTrigger;
import gov.va.med.esr.service.trigger.PersonTriggerEvent;
import gov.va.med.fw.batchprocess.AbstractDataQueryIncrementalProcess;
import gov.va.med.fw.batchprocess.DataQueryProcessExecutionContext;
import gov.va.med.fw.batchprocess.ProcessStatistics;
import gov.va.med.fw.service.trigger.TriggerEvent;
import gov.va.med.fw.service.trigger.TriggerRouter;

import java.util.List;

import org.apache.commons.lang.Validate;

/**
 * Email Deletion Batch Process(ESR 3.11_CodeCR11902).  Delete emails with email address None@None.com
 * and send Z05 messages to notify VistA
 * @author DNS   ZHANG
 */
public class EmailDeletionProcess extends AbstractDataQueryIncrementalProcess {
	private TriggerRouter triggerRouter;
	private EmailDAO emailDAO;
		     
	/**
	 * @see gov.va.med.fw.batchprocess.AbstractDataProcess#processData(gov.va.med.fw.batchprocess.DataProcessExecutionContext,
	 *      java.util.List)
	 */     
	protected void processData(DataQueryProcessExecutionContext context, List acquiredData) {
		if(logger.isInfoEnabled())
			logger.info("Email Deletion batch process: Query increment result Size="+(acquiredData == null ? 0 : acquiredData.size()));
				
		if (acquiredData == null)
			return;
		
	        
       // Add check for isInterrupted so don't have to wait for entire batch to finish
		for (int i = 0; i < acquiredData.size() && !isInterrupted(context); i++) {
            // Object[] returned from get when scrolling (idempotent is false)
            Object[] row = (Object[]) acquiredData.get(i);
            Email email = (Email)row[0];
			String vpid = email.getPerson().getVPIDValue();
            
			if(logger.isDebugEnabled())
				logger.debug("Processing person # " + (i+1) + " with VPID = " + vpid);
			
			try {
				PersonEntityKey personKey = email.getPerson().getPersonEntityKey();
				emailDAO.deleteEmailById(email);
				getTriggerRouter().processTriggerEvent(getTriggerEventZ05Email(personKey));
				context.getProcessStatistics().incrementNumberOfSuccessfulRecords();

			} catch (Exception ex) {
				context.getProcessStatistics().incrementNumberOfErrorRecords();
				String errMsg = "Error while executing Email Deletion batch process.  VPID=" + vpid;
							
				context.getExceptionData().add(errMsg+ " Reason: "+ ex.getMessage());
				if(logger.isWarnEnabled())
					logger.warn(errMsg + " Reason: ", ex);
			}
            
			// Update statistics more frequently than once per batch (default size 500)
            if(context.getProcessStatistics().isTotalNumberMod(DEFAULT_JOB_RESULT_UPDATE_INTERVAL))
                this.updateJobResult(context);
		}
        
		if(logger.isDebugEnabled()) {
			logger.debug("EmailDeletion: Processing of current batch complete.");
			logger.debug("EmailDeletion: Successful records count = "+context.getProcessStatistics().getNumberOfSuccessfulRecords());
			logger.debug("EmailDeletion: Failure records count ="+context.getProcessStatistics().getNumberOfErrorRecords());
           
		}
	}
	
	public TriggerRouter getTriggerRouter() {
		return triggerRouter;
	}


	public void setTriggerRouter(TriggerRouter triggerRouter) {
		this.triggerRouter = triggerRouter;
	}
	
	private TriggerEvent getTriggerEventZ05Email(PersonEntityKey key)
	{
		PersonTriggerEvent triggerEvent = new PersonTriggerEvent(PersonTrigger.DestinationType.MESSAGING,
                PersonTrigger.TargetType.VISTA, PersonTrigger.DispatchType.NOTIFY,  PersonTrigger.DataType.ADDRESS);
		triggerEvent.setPersonId(key);
		return triggerEvent;
	}

	public EmailDAO getEmailDAO() {
		return emailDAO;
	}

	public void setEmailDAO(EmailDAO emailDAO) {
		this.emailDAO = emailDAO;
	}
}