/*******************************************************************************
 * Copyright © 2005 VHA. All rights reserved
 ******************************************************************************/
package gov.va.med.esr.common.persistent.hibernate;

// Java classes

// Library classes

// Framework classes
import gov.va.med.fw.model.AbstractKeyedEntity;

// ESR classes
import org.hibernate.Query;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;

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

/**
 * This class is a JUnit that tests any custom HQL.
 * 
 * @author Andrew Pach
 * @version 3.0
 */
public class CustomHqlTest extends AbstractKeyedEntityDAOTestCase {

	protected DAOTestMode[] setUpTests() {
		return new DAOTestMode[] { TEST_QUERY };
	}

	public void testNamedQueries() {
		try {
			// Build the data retrieval query
			Query dataQuery = getSearchSelectDataQueryString();
			// dataQuery.setFirstResult(0);
			// dataQuery.setMaxResults(Integer.MAX_VALUE);

			List results = dataQuery.list();

			// Return null if no VPID found
			if (results.size() == 0) {
				System.out.println("No results returned.");
			}
			else {
				for (int i = 0; i < results.size(); i++) {
					System.out.println("Displaying result row " + i);
					Object[] data = (Object[]) results.get(i);
					for (int j = 0; j < data.length; j++) {
						System.out.println("Field " + j + ": " + data[j]);
					}
				}
			}
		}
		catch (Exception e) {
			fail("Problem in testNamedQueries method", e);
		}
	}

	/**
	 * Builds and returns a data query.
	 * 
	 * @return the data query
	 * @throws org.hibernate.HibernateException
	 *            if there were any problems building the query
	 */
	private Query getSearchSelectDataQueryString() throws HibernateException {
		// Build the query
		String queryString = "SELECT p1.identifier, p1.VPIDValue, p1.sensitiveRecord "
				+ "FROM Person p1 WHERE p1.identifier in ("
				+ "SELECT p.identifier FROM Person p "
				+ "JOIN p.militaryService.internalMilitaryServiceSiteRecords sites "
				+ "JOIN sites.internalMilitaryServiceEpisodes mse "
				+ "WHERE mse.serviceNumber = :militaryServiceNumber" + ")";

		// Create parameter and value lists
		ArrayList paramList = new ArrayList(1);
		ArrayList valueList = new ArrayList(1);
		paramList.add("militaryServiceNumber");
		valueList.add("123-45-6789");

		System.out.println("Query: " + queryString);

		Query query = null;
		try {
			Session session = this.getCurrentSession();
			
			query = session.createQuery(queryString);
	
			// Prepare the query by filling in the parameters values
			prepareQuery(query, paramList, valueList);
		}
		catch( Exception e ) {
			throw new HibernateException( "failed to get a prepare query", e );
		}

		// Return the final query
		return query;
	}

	/**
	 * Prepares a query by setting parameters in the parameter list with the
	 * values in the value list.
	 * 
	 * @param query
	 *           The query to prepare
	 * @param paramList
	 *           The list of parameters
	 * @param valueList
	 *           The list of parameter values
	 * @throws org.hibernate.HibernateException
	 *            if there was a problem setting the parameters
	 */
	private void prepareQuery(Query query, List paramList, List valueList)
			throws HibernateException {
		for (int i = 0; i < paramList.size(); i++) {
			query.setParameter((String) paramList.get(i), valueList.get(i));
		}
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see AbstractKeyedEntityDAOTestCase#modifyTestObject(gov.va.med.fw.model.AbstractKeyedEntity)
	 */
	protected void modifyTestObject(AbstractKeyedEntity obj) {
		// No updating necessary
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see AbstractKeyedEntityDAOTestCase#setUpTestObject()
	 */
	protected AbstractKeyedEntity setUpTestObject() throws Exception {
		// No setup needed
		return null;
	}
}