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


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

import java.io.Serializable;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.Validate;
import org.springframework.util.StopWatch;

import gov.va.med.esr.common.model.CommonEntityKeyFactory;
import gov.va.med.esr.common.model.person.id.PersonIdEntityKey;
import gov.va.med.esr.service.EEResult;
import gov.va.med.esr.service.PersonService;
import gov.va.med.fw.batchprocess.AbstractDataProcessWorker;
import gov.va.med.fw.batchprocess.ProcessStatistics;

/**
 * Initial javadoc for class MigrateBulkEEProcessWorker.
 * TODO - Add content here
 * 
 * Created Sep 21, 2006 3:26:52 PM
 * @author DNS   BOHMEG
 */
public class MigrateBulkEEProcessWorker extends AbstractDataProcessWorker {
	private PersonService personService;
	
	/* (non-Javadoc)
	 * @see gov.va.med.fw.batchprocess.AbstractDataProcessWorker#processData(java.lang.Object)
	 */
	public ProcessStatistics processData(Object o) throws Exception {
		MigrateBulkEEProcessStatistics stats = new MigrateBulkEEProcessStatistics();
		
		List personIds = null;
		if(o instanceof List)
			personIds = (List) o;
		else if(o instanceof Object[])
			personIds = Arrays.asList((Object[]) o);
		else
			throw new IllegalArgumentException("Input is not a List or Object[] or Person Ids");
		
		Iterator itr = personIds.iterator();
		PersonIdEntityKey key = null;
		
		StopWatch timer = new StopWatch();
		timer.setKeepTaskList(false); // no need to gobble up memory
		
		EEResult result = null;
		while(itr.hasNext()) { 
			key = CommonEntityKeyFactory.createPersonIdEntityKey((Serializable) itr.next());
			
			try {
				timer.start(key.getKeyValueAsString());
				result = personService.processEEForMigratedPerson(key); // note this will internally make sure really needs to have EE migrated
				timer.stop();
				
				if(!result.isCalculated()) {
					stats.incrementNumberOfRecordsNotNeedingEEMigrated(); // will also increment total count
				} else {
					stats.incrementTotalSuccessfulDuration((float) (timer.getLastTaskTimeMillis() / 1000.0)); // will also increment success and total count
					
					if(!result.isEeChange())
						stats.incrementNumberOfEEDidNotChangeRecords();
					
					if(result.getTriggerEventsForBulletins() != null)
						stats.incrementNumberOfBulletinsTriggered(result.getTriggerEventsForBulletins().size());
					if(result.getTriggerEventsForLetters() != null)
						stats.incrementNumberOfLettersTriggered(result.getTriggerEventsForLetters().size());
					if(result.getTriggerEventsForHL7Messages() != null)
						stats.incrementNumberOfHL7MessagesTriggered(result.getTriggerEventsForHL7Messages().size());					
				}				
			} catch(Throwable e) {
				timer.stop(); // reset
				if(logger.isErrorEnabled())
					logger.error("Unable to migrate/calculate EE for Person Id: " + key.getKeyValueAsString(), e);
				stats.incrementNumberOfErrorRecords(); // will also increment total count
			}
		}
		
		return stats;
	}

	/**
	 * @return Returns the personService.
	 */
	public PersonService getPersonService() {
		return personService;
	}

	/**
	 * @param personService The personService to set.
	 */
	public void setPersonService(PersonService personService) {
		this.personService = personService;
	}
	
	public void afterPropertiesSet() {
		Validate.notNull(personService, "personService is required");
	}	
}
