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

package gov.va.med.esr.service.trigger;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.apache.commons.lang.Validate;

import gov.va.med.fw.model.AbstractKeyedEntity;
import gov.va.med.fw.model.EntityKey;

/**
 * General purpose TriggerEvent for a Person that deals with identifying pieces of 
 * information about the Person.  These pieces could be in the form of interested
 * EntityKey's or interested instances of AbstractKeyedEntity's.
 * 
 * <p>All information about the "partial" pieces will be condensed to entity key format
 * in the preTriggerInit.  This avoids placing entire BOM objects on the queue mechanism.
 * 
 * Created Aug 22, 2005 6:07:27 PM
 * 
 * @author DNS   BOHMEG
 */
public class PartialPersonTriggerEvent extends TargetedPersonTriggerEvent {
	/**
	 * 
	 */
	private static final long serialVersionUID = -2075833362750026969L;
	/**
	 * Contains EntityKey's or instances of the AbstractKeyedEntity of constituent
	 * objects that are of interest for this event. Interpretation of these is
	 * based on the CommonTriggerData.
	 */
	private Set keyedEntities = new HashSet();

	public PartialPersonTriggerEvent(PersonTrigger.DestinationType destinationType,
            PersonTrigger.TargetType targetType,
			PersonTrigger.DispatchType dispatchType,
			PersonTrigger.DataType dataType) {
		super(destinationType, targetType, dispatchType, dataType);
	}

	public PartialPersonTriggerEvent(PersonTrigger.DestinationType destinationType,
            PersonTrigger.TargetType targetType,
			PersonTrigger.DispatchType dispatchType,
			PersonTrigger.DataType dataType, Set entityKeys) {
		this(destinationType, targetType, dispatchType, dataType);
		setEntityKeys(entityKeys);
	}

	/**
	 * @return Returns the entityKeys.
	 */
	public Set getEntityKeys() {
		return keyedEntities;
	}
	
	public void addEntityKey(EntityKey key) {
		Validate.notNull(key, "EntityKey is null");
		keyedEntities.add(key);
	}

	public void addKeyedEntity(AbstractKeyedEntity keyedEntity) {
		Validate.notNull(keyedEntity, "AbstractKeyedEntity is null");
		EntityKey key = keyedEntity.getEntityKey();
		if(key == null)
			keyedEntities.add(keyedEntity);
		else
			keyedEntities.add(key);
	}
	
	/**
	 * @param entityKeys
	 *            The entityKeys to set.
	 */
	public void setEntityKeys(Set entityKeys) {
		Validate.notNull(entityKeys, "entityKeys is null");
		this.keyedEntities = entityKeys;
	}
	
	protected void preTrigger() {
		super.preTrigger();
		if(keyedEntities.isEmpty())
			return;
		
		Set keys = new HashSet(keyedEntities.size());
		// ensure that all elements of keyedEntities are the actual key
		Iterator itr = keyedEntities.iterator();
		Object item = null;
		while(itr.hasNext()) {
			item = itr.next();
			if(item instanceof EntityKey)
				keys.add(item);
			else if(item instanceof AbstractKeyedEntity) {
				EntityKey key = ((AbstractKeyedEntity) item).getEntityKey();
				if(key != null)
					keys.add(key);
				else
					throw new IllegalStateException("PartialPersonTriggerEvent contains an AbstractKeyedEntity with a null EntityKey");					
			} else
				throw new IllegalStateException("PartialPersonTriggerEvent contains an item that is not an EntityKey nor is it " +
						"an instance of AbstractKeyedEntity");
		}
		keyedEntities.clear();
		keyedEntities.addAll(keys);
	}
}
