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

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

import java.math.BigDecimal;
import java.util.List;

import org.apache.commons.lang.Validate;

import gov.va.med.esr.common.model.person.id.PersonEntityKey;
import gov.va.med.esr.common.model.person.id.PersonIdEntityKeyImpl;
import gov.va.med.esr.service.GenerateQRYZ11MessagingService;
import gov.va.med.esr.service.impl.GenerateQRYZ11MessagingServiceImpl;
import gov.va.med.fw.batchprocess.AbstractDataQueryIncrementalProcess;
import gov.va.med.fw.batchprocess.DataQueryProcessExecutionContext;
import gov.va.med.fw.service.ServiceException;

/**
 * Generates QRY-Z11 messages to send to VBA for people with a VBA Query Status
 * of VBA Query Initiated or VBA Queried - Pending Response.
 * 
 * Created Aug 18, 2008 2:39:36 PM
 * @author DNS   GALLAS
 */
public class GenerateQRYZ11Process extends AbstractDataQueryIncrementalProcess {
	
    private GenerateQRYZ11MessagingService messagingService = null;
    
    protected void processData(DataQueryProcessExecutionContext context, List acquiredData) {
        if(logger.isDebugEnabled())
            logger.debug(/*Generate QRY-Z11:*/ getProcessName() + ": 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);
            BigDecimal personId = (BigDecimal) row[0];
            
            PersonEntityKey key = new PersonIdEntityKeyImpl(personId);
            
            if(logger.isDebugEnabled())
                logger.debug("Processing person # " + (i+1) + " with id = " + personId);
            
            try {
               processRecord(key, row);
               context.getProcessStatistics().incrementNumberOfSuccessfulRecords();
            } catch (Exception ex) {
                context.getProcessStatistics().incrementNumberOfErrorRecords();
                String errMsg = "Error while executing " + getProcessName() + " for person "
                                + personId;
                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(/*Generate QRY-Z11:*/ getProcessName() + ": Processing of current batch complete.");
            logger.debug(/*Generate QRY-Z11:*/ getProcessName() + ": Successful records count = "+context.getProcessStatistics().getNumberOfSuccessfulRecords());
            logger.debug(/*Generate QRY-Z11:*/ getProcessName() + ": Failure records count ="+context.getProcessStatistics().getNumberOfErrorRecords());
        }
    }	

    /**
     * Processes data for a particular person
     * @param key
     * @param VPID
     * @throws ServiceException 
     */
    protected void processRecord(PersonEntityKey key, Object[] dataRow) throws Exception 
    {
        String VPID = (String) dataRow[1];
       	messagingService.generateMessage(key, VPID);
    }
        
    /**
     * @param messagingService
     *            The messagingService to set.
     */
    public void setMessagingService(GenerateQRYZ11MessagingService messagingService) {
        this.messagingService = messagingService;
    }

    protected GenerateQRYZ11MessagingService getMessagingService() {
    	return messagingService;
    }
    
    public void afterPropertiesSet() {
        super.afterPropertiesSet();
        Validate.notNull(messagingService, "A MessagingService is needed");
        Validate.isTrue(!(messagingService instanceof GenerateQRYZ11MessagingServiceImpl), 
                "A GenerateQRYZ11 Messaging Service is required");
    }
}
