
package gov.va.med.cds.persistence.hibernate;

import gov.va.med.cds.common.person.correlation.PersonIdentifierInterface;
import gov.va.med.cds.filter.EntryFilterInterface;
import gov.va.med.cds.persistence.PersistenceException;
import gov.va.med.cds.persistence.QueryStrategyInterface;
import gov.va.med.cds.persistence.QueryWorkInterface;
import gov.va.med.cds.template.generated.JaxBMarshallerUnmarshallerInterface;

import java.util.ArrayList;
import java.util.List;

import org.dom4j.Document;

/**
 * 
 * @author vhaislegberb
 *
 *
 *         This <code>DefaultHibernateReadPerstenceManager</code> class is the
 *         read persistence manager to used when the query being used accepts a
 *         list of person identifiers in the form of
 *         <code>assigningFacility/identity</code>. The intent is to use the
 *         list of person identifiers in an 'in' expression in the query. The
 *         entry filter passed to the perform read method may or may not add
 *         dates or record identifiers to query by as well. This persistence
 *         manager does not support querying by person identifiers, start and
 *         end dates, and record identifiers however.
 */
public class DefaultHibernateReadPersistenceManager extends AbstractReadHibernatePersistenceManager {

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * gov.va.med.cds.persistence.ReadPersistenceManagerInterface#isApplicable(
	 * gov.va.med.cds.filter.EntryFilterInterface, java.util.List)
	 */
	public boolean isApplicable(EntryFilterInterface aEntryFilter, List<PersonIdentifierInterface> personIdentifiers)
			throws PersistenceException {
		return (super.isApplicable(aEntryFilter, personIdentifiers)
				&& (!aEntryFilter.isPatientCentricFilter() || personIdentifiers.size() > 0));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see gov.va.med.cds.persistence.hibernate.
	 * AbstractReadHibernatePersistenceManager#createQueryWork(gov.va.med.cds.
	 * persistence.QueryStrategyInterface,
	 * gov.va.med.cds.filter.EntryFilterInterface, java.util.List,
	 * java.lang.Class)
	 */
	protected List<QueryWorkInterface> createQueryWork(QueryStrategyInterface queryStrategy,
			EntryFilterInterface entryFilter, List<PersonIdentifierInterface> personIdentifiers,
			Class<?> pointInTimeUserType, String siteId, JaxBMarshallerUnmarshallerInterface marshallerUnmarshaller) {
		return queryStrategy.createQueryWork(getSessionFactory(entryFilter.getTemplateId()), entryFilter,
				concatenatePersonIdentifiers(personIdentifiers), pointInTimeUserType, siteId, marshallerUnmarshaller);
	}

	/**
	 * Concatenates the assigning facility (station no) with the identity.
	 * 
	 * @param personIdentifiers
	 * @return
	 */
	private List<String> concatenatePersonIdentifiers(List<PersonIdentifierInterface> personIdentifiers) {
		List<String> concatenatedPersonIdentifiers = new ArrayList<String>();

		if (personIdentifiers != null) {
			for (PersonIdentifierInterface pid : personIdentifiers) {
				concatenatedPersonIdentifiers
						.add(String.format("%s/%s", pid.getAssigningFacility(), pid.getIdentity()));
			}
		}

		return concatenatedPersonIdentifiers;
	}

	public String getSiteIdentifier() {
		return super.getSiteIdentifier();
	}

}
