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

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

import gov.va.med.esr.common.model.person.id.PersonIdEntityKeyImpl;
import gov.va.med.esr.service.EligibilityEnrollmentService;
import gov.va.med.fw.batchprocess.AbstractDataQueryIncrementalProcess;
import gov.va.med.fw.batchprocess.DataQueryProcessExecutionContext;
import gov.va.med.fw.batchprocess.ProcessStatistics;

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

import org.apache.commons.lang.Validate;

/**
 * Batch Process for the Expire Means Test use case.
 * 
 * @author DNS   MANSOG
 */
public class ExpireMeansTestProcess extends AbstractDataQueryIncrementalProcess {
	private EligibilityEnrollmentService	eligibilityEnrollmentService	= null;

	protected ProcessStatistics createProcessStatistics() {
	    return new ExpireMeansTestProcessStatistics();
    }   
     
	/**
	 * @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("Expire MeansTest 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);
			BigDecimal personId = (BigDecimal) row[0];
			
			if(logger.isDebugEnabled())
				logger.debug("Processing person # " + (i+1) + " with id = " + personId);
			try {
				if (eligibilityEnrollmentService.processExpiredMeansTestForBatchProcess(new PersonIdEntityKeyImpl(personId))) {
				    context.getProcessStatistics().incrementNumberOfSuccessfulRecords();
                }else {
                    //Record is not processed as the Veteran is not subject to Means Test
                    ((ExpireMeansTestProcessStatistics) context.getProcessStatistics()).incrementNumberOfNotSubjectToMeansTestRecords();
                }
			} catch (Exception ex) {
				context.getProcessStatistics().incrementNumberOfErrorRecords();
				String errMsg = "Error while executing Expire MeansTest batch process 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("ExpireMeansTest: Processing of current batch complete.");
			logger.debug("ExpireMeansTest: Successful records count = "+context.getProcessStatistics().getNumberOfSuccessfulRecords());
			logger.debug("ExpireMeansTest: Failure records count ="+context.getProcessStatistics().getNumberOfErrorRecords());
            logger.debug("ExpireMeansTest: Not subject to means test records count ="+
                    ((ExpireMeansTestProcessStatistics)context.getProcessStatistics()).getNumberOfNotSubjectToMeansTestRecords());
		}
	}

	/**
	 * @return Returns the eligibilityEnrollmentService.
	 */
	public EligibilityEnrollmentService getEligibilityEnrollmentService() {
		return eligibilityEnrollmentService;
	}

	/**
	 * @param eligibilityEnrollmentService
	 *            The eligibilityEnrollmentService to set.
	 */
	public void setEligibilityEnrollmentService(
			EligibilityEnrollmentService eligibilityEnrollmentService) {
		this.eligibilityEnrollmentService = eligibilityEnrollmentService;
	}

	public void afterPropertiesSet() {
		super.afterPropertiesSet();
		Validate.notNull(eligibilityEnrollmentService,
				"A EligibilityEnrollmentService is needed");
	}
}
