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

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

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

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;

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.person.id.PersonIdEntityKeyImpl;
import gov.va.med.esr.common.model.ee.EligibilityVerification;
import gov.va.med.esr.common.model.lookup.AACIndicator;
import gov.va.med.esr.service.GenerateQRYZ11MessagingService;
import gov.va.med.esr.service.LookupService;
import gov.va.med.esr.service.PersonService;
import gov.va.med.esr.service.CommsEmailBulletinService;
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.batchprocess.ProcessStatisticsHandler;
import gov.va.med.fw.batchprocess.ProcessStatistics;
import gov.va.med.fw.batchprocess.model.JobConfig;
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 CheckUnprocessedVBAQueryRecords extends AbstractDataQueryIncrementalProcess {
	
    private CommsEmailBulletinService bulletinService;  
    private ProcessStatisticsHandler processStatisticsHandler;
    private StringBuffer emailTextBuffer;
    
    protected void processData(DataQueryProcessExecutionContext context, List acquiredData) {
        if(logger.isDebugEnabled())
            logger.debug(/*Generate Query VBA:*/ getProcessName() + ": Query increment result Size="+(acquiredData == null ? 0 : acquiredData.size()));
        
        if (acquiredData == null)
             return;
        
        this.emailTextBuffer = new StringBuffer();
        
        // 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 (context.getProcessStatistics()!=null && context.getProcessStatistics().getNumberOfTotalRecords() > 0){
        	try {			
        		this.sendEmailNotification(context);				
    		} catch (Exception ex) {
    			String errMsg = "Error sending bulletin notification for Unprocessed VBA Queries";
    			context.getExceptionData().add(errMsg+ " Reason: "+ ex.getMessage());
    			if(logger.isWarnEnabled())
    				logger.warn(errMsg + " Reason: ", ex);
    		}
        }
        
        if(logger.isDebugEnabled()) {
            logger.debug(/*Generate Query VBA:*/ getProcessName() + ": Processing of current batch complete.");
            logger.debug(/*Generate Query VBA1:*/ getProcessName() + ": Successful records count = "+context.getProcessStatistics().getNumberOfSuccessfulRecords());
            logger.debug(/*Generate Query VBA:*/ 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 
    {
    	BigDecimal personId = (BigDecimal) dataRow[0];
    	// String VPID = (String) dataRow[1];
    	BigDecimal HL7_LOG_id = (BigDecimal) dataRow[1];
      
    	emailTextBuffer.append("\n");
        emailTextBuffer.append(personId.toString());
        emailTextBuffer.append("|");
        emailTextBuffer.append(HL7_LOG_id.toString());
    }
    
    private void sendEmailNotification(DataQueryProcessExecutionContext context) throws ServiceException {
    	
    	  this.processStatisticsHandler = this.getProcessStatisticsHandler();
          try{
          	if(this.processStatisticsHandler!= null) {
          		JobConfig config = this.getBatchProcessService().getJobConfig(getJobName(context),getJobGroupName(context));
          		
          		String subject = "List of UNprocessed VBA Queries";
          		if(config != null && StringUtils.isNotBlank(config.getEmailDistributionList()) ) {
          			List emailList = config.getEmailsAsList();
          			this.bulletinService.sendSimpleMailMessage(null, (String[])emailList.toArray(new String[0]), null, subject, emailTextBuffer.toString());
          			logger.info("CheckUnprocessedVBAQueryRecords batch job - email of unprocessed list was sent to "+ config.getEmailDistributionList()+"\n");
          		}
          		else{
          			List defaultEmailList = new ArrayList();
        			defaultEmailList.add("PII                  ");
        			processStatisticsHandler.processStatisticsWithDynamicRecipients(context.getProcessStatistics(), defaultEmailList);
        			logger.info("CheckUnprocessedVBAQueryRecords batch job - email of total unprocessed count was sent to PII                  \n");
          			this.bulletinService.sendSimpleMailMessage(null, (String[]) defaultEmailList.toArray(new String[0]), null, subject, emailTextBuffer.toString());
          			logger.info("CheckUnprocessedVBAQueryRecords batch job - email of unprocessed list was sent to PII                  \n");
          		}
          	}
          }catch (Exception ex) {
  	        	logger.error("CheckUnprocessedVBAQueryRecords - ERROR send email of UNprocessed VBA queries ", ex);
  	      }
    }

	public CommsEmailBulletinService getBulletinService() {
		return bulletinService;
	}
	/**
	 * @param bulletinService The bulletinService to set.
	 */
	public void setBulletinService(CommsEmailBulletinService bulletinService) {
		this.bulletinService = bulletinService;
	}

    public void afterPropertiesSet() {
        super.afterPropertiesSet();
        Validate.notNull(bulletinService);
    }
    
}
