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

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

import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.service.trigger.CommonTrigger.DestinationType;
import gov.va.med.esr.service.trigger.CommonTrigger.DispatchType;
import gov.va.med.esr.service.trigger.CommonTrigger.TargetType;
import gov.va.med.esr.service.trigger.PersonTrigger.DataType;
import gov.va.med.fw.model.AbstractKeyedEntity;
import gov.va.med.fw.model.EntityKey;

/**
 * Outgoing messages get the Person's associated sites of record and send them out to all the sites.
 * The attributes "sites" in this class stores the sites which need to be filtered out.
 *  
 * @author Rajiv Patnaik
 * Created on Jul 7, 2006
 * @version 1.0
 * 
 * Copyright © 2006 VHA. All rights reserved
 */
public class FilterSitesPersonTriggerEvent extends PartialPersonTriggerEvent
{
    /**
	 * 
	 */
	private static final long serialVersionUID = 3106640807175287612L;
	/**
     * Sites to be filtered out before sending the messages.  
     */
    private Map entityKeysAndSites = new HashMap();
    
    /**
     * @param destinationType
     * @param targetType
     * @param dispatchType
     * @param dataType
     */
    public FilterSitesPersonTriggerEvent(DestinationType destinationType, TargetType targetType, DispatchType dispatchType, DataType dataType)
    {
        super(destinationType, targetType, dispatchType, dataType);
    }

	public FilterSitesPersonTriggerEvent(PersonTrigger.DestinationType destinationType,
            PersonTrigger.TargetType targetType,
			PersonTrigger.DispatchType dispatchType,
			PersonTrigger.DataType dataType, Map entityKeysAndSites ) {
		this(destinationType, targetType, dispatchType, dataType);
		setEntityKeysAndSites(entityKeysAndSites);
	}    

	
    /**
     * @return Returns the entityKeysAndSites.
     */
    public Map getEntityKeysAndSites()
    {
        return entityKeysAndSites;
    }
    /**
     * @param entityKeysAndSites The entityKeysAndSites to set.
     */
    public void setEntityKeysAndSites(Map entityKeysAndSites)
    {
        this.entityKeysAndSites = entityKeysAndSites;
    }
    
    
    /**
     * Overrides the method from the TargetedPersonTriggerEvent superclass
     * 
     * @return Returns the sites.
     */
    public Set getFilterSites()
    {
        if (super.getFilterSites() != null)
        {
            return getFilterSites();
        }else if (entityKeysAndSites != null)
        {
            Set entityKeySites = new HashSet();
            
            for (Iterator iter = entityKeysAndSites.values().iterator(); iter.hasNext();)
            {
                VAFacility entityKeySite = (VAFacility) iter.next();
                entityKeySites.add(entityKeySite);
            }
           return entityKeySites; 
        }
        return null;
    }

	protected void preTrigger() {
		super.preTrigger();
		if(this.entityKeysAndSites.isEmpty())
			return;
		
		Map keysAndSites = new HashMap(entityKeysAndSites.size());
		// ensure that all elements of keyedEntities are the actual key
		
		for (Iterator iterator = this.entityKeysAndSites.entrySet().iterator(); iterator
				.hasNext();) {

			Map.Entry entry = (Map.Entry) iterator.next();
			Object key = (Object) entry.getKey();
			Object facility = (Object) entry.getValue();

			if (key instanceof EntityKey)
				keysAndSites.put(key, facility);
			else if (key instanceof AbstractKeyedEntity) {
				EntityKey entityKey = ((AbstractKeyedEntity) key)
						.getEntityKey();
				if (entityKey != null)
					keysAndSites.put(entityKey, facility);
				else
					throw new IllegalStateException(
							"FilterSitesPersonTriggerEvent contains an AbstractKeyedEntity with a null EntityKey "
									+ entityKeysAndSites);
			} else {

				throw new IllegalStateException(
						"FilterSitesPersonTriggerEvent contains an item that is not an EntityKey nor is it "
								+ " instance of AbstractKeyedEntity "
								+ entityKeysAndSites);
			}
		}
		entityKeysAndSites.clear();
		entityKeysAndSites.putAll(keysAndSites);
	}
    
} 
