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


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

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.Validate;

import gov.va.med.esr.service.trigger.CommonTrigger;
import gov.va.med.esr.service.trigger.CommonTriggerEvent;
import gov.va.med.esr.service.trigger.CommonTriggerIdentity;
import gov.va.med.fw.batchprocess.AbstractPublishQueryResultsToWorkers;
import gov.va.med.fw.batchprocess.DataQueryProcessExecutionContext;
import gov.va.med.fw.batchprocess.ProcessStatistics;
import gov.va.med.fw.service.trigger.TriggerEvent;

/**
 * Executes bulk Eligiblity and Enrollment calculations against recently migrated
 * Person records.  "Migrated" in the sense that these records were imported into ESR
 * and have not yet had their EE calculated by current ESR business rules.
 * 
 * Created Sep 13, 2006 10:31:04 AM
 * @author DNS   BOHMEG
 */
public class MigrateBulkEEProcess extends AbstractPublishQueryResultsToWorkers {
	private final String CUSTOM_PERSON_IDS = "customPersonIds";
	private final String PREFIX_MAX_NUMBER_TO_MIGRATE = "-size=";
	private String triggerEventName;
	
	protected ProcessStatistics createProcessStatistics() {
		return new MigrateBulkEEProcessStatistics();
	}	
	
	/** Allows for passing in of Person Id(s) to get the data to be migrated */
	protected List doAcquireData(DataQueryProcessExecutionContext context) throws Exception {
		if(context.getExecutionArguments() == null)
			return super.doAcquireData(context);

		// custom behavior below to support various executionArguments
		
		if(context.getContextData().containsKey(MAX_RECORDS_QUERIED)) {
			// this has already been setup...check against the max
			return super.doAcquireData(context);
		}
		
		if(context.getContextData().containsKey(CUSTOM_PERSON_IDS)) {
			// this has already been take care of so no more data is needed
			return null;
		}
						
		Object args = context.getExecutionArguments();
		
		// a) check for Person Ids
		if(args instanceof Object[]) {
			List personIds = new ArrayList();
			Object[] argsArray = (Object[]) args;
			for(int i=0; i<argsArray.length; i++)
				personIds.add(new BigDecimal(argsArray[i].toString()));
			// makes sure this is only run once
			context.getContextData().put(CUSTOM_PERSON_IDS, null);
			context.getContextData().put(TOTAL_QUERY_COUNT, new Integer(personIds.size())); // custom total count to use
			return personIds;
		}
		
		String singleArg = (String) args;
		
		// b) check to see if this "-size=nnn" argument
		if(singleArg.startsWith(PREFIX_MAX_NUMBER_TO_MIGRATE)) {
			// get the number from the singleArg
			String maxNumberToMigrate = singleArg.substring(PREFIX_MAX_NUMBER_TO_MIGRATE.length());
			Integer maxNumber = new Integer(maxNumberToMigrate);
			context.getContextData().put(MAX_RECORDS_QUERIED, maxNumber); // custom total count to use
			return super.doAcquireData(context);
		}
		
		// c) must be a single PersonId
		List personIds = new ArrayList();
		personIds.add(new BigDecimal(singleArg));
		// makes sure this is only run once
		context.getContextData().put(CUSTOM_PERSON_IDS, null);
		context.getContextData().put(TOTAL_QUERY_COUNT, new Integer(1)); // custom total count to use
		return personIds;
	}
			
	
	/* (non-Javadoc)
	 * @see gov.va.med.fw.batchprocess.AbstractPublishQueryResultsToWorkers#getTriggerEvent(gov.va.med.fw.batchprocess.DataQueryProcessExecutionContext, java.util.List)
	 */
	protected TriggerEvent getTriggerEvent(DataQueryProcessExecutionContext context, List acquiredData) {
		List personIds = new ArrayList();
		Iterator itr = acquiredData.iterator();
		Object item = null;
		while(itr.hasNext()) {
			item = itr.next();
			if(item instanceof Object[])
				personIds.add(((Object[]) item)[0]);
			else
				personIds.add(item);
		}
		return new CommonTriggerEvent(triggerEventName, (Serializable) personIds, new CommonTriggerIdentity(CommonTrigger.DestinationType.BATCH_PROCESS));
	}

	/**
	 * @return Returns the triggerEventName.
	 */
	public String getTriggerEventName() {
		return triggerEventName;
	}

	/**
	 * @param triggerEventName The triggerEventName to set.
	 */
	public void setTriggerEventName(String triggerEventName) {
		this.triggerEventName = triggerEventName;
	}
	
	public void afterPropertiesSet() {
		super.afterPropertiesSet();
		Validate.notNull(triggerEventName, "triggerEventName is required");
	}
}
