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

import gov.va.med.cds.junit.runners.Suite;

import java.util.HashMap;
import java.util.Map;

import org.dom4j.Element;
import org.easymock.EasyMock;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.type.StandardBasicTypes;
import org.junit.Test;

public class ConfigurableNamedQueryEntityLocatorTest {

	@Test
	@Suite( groups = { "checkintest" } )
    public void testFindSimple() {
		Map<String, String> queryParameterMap = new HashMap<String, String>();
		queryParameterMap.put("param1", "elementName");
		
		Session session = EasyMock.createMock( Session.class );
		Query query = EasyMock.createMock( Query.class );
		Element myElement = EasyMock.createMock( Element.class );
		Element entityElement = EasyMock.createMock(Element.class);
		
		EasyMock.expect(session.getNamedQuery("queryName")).andReturn(query);
		EasyMock.expect(myElement.elementTextTrim("elementName")).andReturn("paramValue");
		EasyMock.expect(query.setParameter("param1", "paramValue", StandardBasicTypes.STRING)).andReturn(query);
		EasyMock.expect(query.uniqueResult()).andReturn( entityElement );
		
		EasyMock.replay(session, query, myElement, entityElement);
		
		ConfigurableNamedQueryEntityLocator locator = new ConfigurableNamedQueryEntityLocator();
		locator.setQueryName("queryName");
		locator.setQueryParameterMap(queryParameterMap);
		
		locator.find(session, myElement);
		
		EasyMock.verify(session, query, myElement, entityElement);
	}
	
	@Test
	@Suite( groups = { "checkintest" } )
    public void testFindComplex() {
		Map<String, String> queryParameterMap = new HashMap<String, String>();
		queryParameterMap.put("param1", "root.parent.elementName");
		
		Session session = EasyMock.createMock( Session.class );
		Query query = EasyMock.createMock( Query.class );
		Element myElement = EasyMock.createMock( Element.class );
		Element entityElement = EasyMock.createMock(Element.class);
		
		EasyMock.expect(session.getNamedQuery("queryName")).andReturn(query);
		
		EasyMock.expect(myElement.element("root")).andReturn(myElement);
		EasyMock.expect(myElement.element("parent")).andReturn(myElement);
		EasyMock.expect(myElement.elementTextTrim("elementName")).andReturn("paramValue");
		EasyMock.expect(query.setParameter("param1", "paramValue", StandardBasicTypes.STRING)).andReturn(query);
		EasyMock.expect(query.uniqueResult()).andReturn( entityElement );
		
		EasyMock.replay(session, query, myElement, entityElement);
		
		ConfigurableNamedQueryEntityLocator locator = new ConfigurableNamedQueryEntityLocator();
		locator.setQueryName("queryName");
		locator.setQueryParameterMap(queryParameterMap);
		
		locator.find(session, myElement);
		
		EasyMock.verify(session, query, myElement, entityElement);
		
	}
	
	@Test
	@Suite( groups = { "checkintest" } )
    public void testFindComplexMultiParameter() {
		Map<String, String> queryParameterMap = new HashMap<String, String>();
		queryParameterMap.put("identity", "documentIdentifier.identity");
		queryParameterMap.put("namespaceId", "documentIdentifier.namespaceId");
		queryParameterMap.put("universalId", "documentIdentifier.universalId");
		queryParameterMap.put("universalIdType", "documentIdentifier.universalIdType");
		
		Session session = EasyMock.createMock( Session.class );
		Query query = EasyMock.createMock( Query.class );
		Element myElement = EasyMock.createMock( Element.class );
		Element entityElement = EasyMock.createMock(Element.class);
		
		EasyMock.expect(session.getNamedQuery("queryName")).andReturn(query);
		
		EasyMock.expect(myElement.element("documentIdentifier")).andReturn(myElement);
		EasyMock.expect(myElement.elementTextTrim("universalId")).andReturn("universalIdVal");
		EasyMock.expect(query.setParameter("universalId", "universalIdVal", StandardBasicTypes.STRING)).andReturn(query);
		
		EasyMock.expect(myElement.element("documentIdentifier")).andReturn(myElement);
		EasyMock.expect(myElement.elementTextTrim("identity")).andReturn("identityVal");
		EasyMock.expect(query.setParameter("identity", "identityVal", StandardBasicTypes.STRING)).andReturn(query);
		
		EasyMock.expect(myElement.element("documentIdentifier")).andReturn(myElement);
		EasyMock.expect(myElement.elementTextTrim("namespaceId")).andReturn("namespaceIdVal");
		EasyMock.expect(query.setParameter("namespaceId", "namespaceIdVal", StandardBasicTypes.STRING)).andReturn(query);
		
		EasyMock.expect(myElement.element("documentIdentifier")).andReturn(myElement);
		EasyMock.expect(myElement.elementTextTrim("universalIdType")).andReturn("universalIdTypeVal");
		EasyMock.expect(query.setParameter("universalIdType", "universalIdTypeVal", StandardBasicTypes.STRING)).andReturn(query);
		
		EasyMock.expect(query.uniqueResult()).andReturn( entityElement );
		
		EasyMock.replay(session, query, myElement, entityElement);
		
		ConfigurableNamedQueryEntityLocator locator = new ConfigurableNamedQueryEntityLocator();
		locator.setQueryName("queryName");
		locator.setQueryParameterMap(queryParameterMap);
		
		locator.find(session, myElement);
		
		EasyMock.verify(session, query, myElement, entityElement);
		
	}
	
	@Test
	@Suite( groups = { "checkintest" } )
    public void testFindComplexMultiParameterWithNulls() {
		Map<String, String> queryParameterMap = new HashMap<String, String>();
		queryParameterMap.put("identity", "documentIdentifier.identity");
		queryParameterMap.put("namespaceId", "documentIdentifier.namespaceId");
		queryParameterMap.put("universalId", "documentIdentifier.universalId");
		queryParameterMap.put("universalIdType", "documentIdentifier.universalIdType");
		
		Session session = EasyMock.createMock( Session.class );
		Query query = EasyMock.createMock( Query.class );
		Element myElement = EasyMock.createMock( Element.class );
		Element entityElement = EasyMock.createMock(Element.class);
		
		EasyMock.expect(session.getNamedQuery("queryName")).andReturn(query);
		
		EasyMock.expect(myElement.element("documentIdentifier")).andReturn(myElement);
		EasyMock.expect(myElement.elementTextTrim("universalId")).andReturn("universalIdVal");
		EasyMock.expect(query.setParameter("universalId", "universalIdVal", StandardBasicTypes.STRING)).andReturn(query);
		
		EasyMock.expect(myElement.element("documentIdentifier")).andReturn(myElement);
		EasyMock.expect(myElement.elementTextTrim("identity")).andReturn(null);
		EasyMock.expect(query.setParameter("identity", null, StandardBasicTypes.STRING)).andReturn(query);
		
		EasyMock.expect(myElement.element("documentIdentifier")).andReturn(myElement);
		EasyMock.expect(myElement.elementTextTrim("namespaceId")).andReturn(null);
		EasyMock.expect(query.setParameter("namespaceId", null, StandardBasicTypes.STRING)).andReturn(query);
		
		EasyMock.expect(myElement.element("documentIdentifier")).andReturn(myElement);
		EasyMock.expect(myElement.elementTextTrim("universalIdType")).andReturn(null);
		EasyMock.expect(query.setParameter("universalIdType", null, StandardBasicTypes.STRING)).andReturn(query);
		
		EasyMock.expect(query.uniqueResult()).andReturn( entityElement );
		
		EasyMock.replay(session, query, myElement, entityElement);
		
		ConfigurableNamedQueryEntityLocator locator = new ConfigurableNamedQueryEntityLocator();
		locator.setQueryName("queryName");
		locator.setQueryParameterMap(queryParameterMap);
		
		locator.find(session, myElement);
		
		EasyMock.verify(session, query, myElement, entityElement);
		
	}

}
