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

import static org.junit.Assert.*;
import static org.easymock.EasyMock.*;

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

import gov.va.med.cds.filter.EntryFilterInterface;
import gov.va.med.cds.filter.ParameterMapInterface;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class LegacyQueryNameBuilderTest
{

    @Before
    public void setUp( )
        throws Exception
    {
    }


    @After
    public void tearDown( )
        throws Exception
    {
    }


    @Test
    public void testBuildQueryNameHasRecordIdentifiersAndXpath( )
    {
        String associationName = "association";
        
        // create mock classes to use in test
        EntryFilterInterface entryFilter = createMock(EntryFilterInterface.class);
        
        // set the expectations for the mocks
        expect( entryFilter.getTemplateId()).andReturn( "templateId" );
        expect( entryFilter.getDomainEntryPoint()).andReturn( "domainEntryPoint" );
        expect( entryFilter.hasRecordIdentifiers()).andReturn( true );
        expect( entryFilter.getAdditionalParametersMap()).andReturn( null );
        expect( entryFilter.containsXpathFilterExpression()).andReturn( true );
        
        
        // prepare the mocks for use in test
        replay( entryFilter );
        
        QueryNameBuilderInterface queryNameBuilder = new LegacyQueryNameBuilder();
        String queryName = queryNameBuilder.buildQueryName( entryFilter, associationName );
        
        // verify that expectations were met
        assertEquals( "templateId.domainEntryPoint.association.identifiers.xpath", queryName );
        verify( entryFilter );
    }
    
    @Test
    public void testBuildQueryNameUsesDates( )
    {
        String associationName = "association";
        
        // create mock classes to use in test
        EntryFilterInterface entryFilter = createMock(EntryFilterInterface.class);
        
        // set the expectations for the mocks
        expect( entryFilter.getTemplateId()).andReturn( "templateId" );
        expect( entryFilter.getDomainEntryPoint()).andReturn( "domainEntryPoint" );
        expect( entryFilter.hasRecordIdentifiers()).andReturn( false );
        expect( entryFilter.useDates()).andReturn( true );
        expect( entryFilter.getAdditionalParametersMap()).andReturn( null );
        expect( entryFilter.containsXpathFilterExpression()).andReturn( false );
        
        
        // prepare the mocks for use in test
        replay( entryFilter );
        
        QueryNameBuilderInterface queryNameBuilder = new LegacyQueryNameBuilder();
        String queryName = queryNameBuilder.buildQueryName( entryFilter, associationName );
        
        // verify that expectations were met
        assertEquals( "templateId.domainEntryPoint.association.date", queryName );
        verify( entryFilter );
    }
    
    
    @Test
    public void testBuildQueryNameUsesDatesAndAdditionalParameters( )
    {
        String associationName = "association";
        
        // create mock classes to use in test
        EntryFilterInterface entryFilter = createMock(EntryFilterInterface.class);
        ParameterMapInterface additionalParams = createMock( ParameterMapInterface.class );
        Set<String> filterNames = createMock( Set.class );
        Iterator<String> filterNamesIterator = createMock( Iterator.class );
        
        // set the expectations for the mocks
        expect( entryFilter.getTemplateId()).andReturn( "templateId" );
        expect( entryFilter.getDomainEntryPoint()).andReturn( "domainEntryPoint" );
        expect( entryFilter.hasRecordIdentifiers()).andReturn( false );
        expect( entryFilter.useDates()).andReturn( true );
        expect( entryFilter.getAdditionalParametersMap()).andReturn( additionalParams );
        expect( entryFilter.containsXpathFilterExpression()).andReturn( false );
        expect( additionalParams.getFilterParameterNames()).andReturn( filterNames );
        expect( filterNames.iterator()).andReturn( filterNamesIterator );
        expect( filterNamesIterator.hasNext()).andReturn( true );
        expect( filterNamesIterator.next()).andReturn( "1" );
        expect( filterNamesIterator.hasNext()).andReturn( true );
        expect( filterNamesIterator.next()).andReturn( "2" );
        expect( filterNamesIterator.hasNext()).andReturn( true );
        expect( filterNamesIterator.next()).andReturn( "3" );
        expect( filterNamesIterator.hasNext()).andReturn( false );
        
        // prepare the mocks for use in test
        replay( entryFilter, additionalParams, filterNames, filterNamesIterator );
        
        QueryNameBuilderInterface queryNameBuilder = new LegacyQueryNameBuilder();
        String queryName = queryNameBuilder.buildQueryName( entryFilter, associationName );
        
        // verify that expectations were met
        assertEquals( "templateId.domainEntryPoint.association.date.1.2.3", queryName );
        verify( entryFilter, additionalParams, filterNames, filterNamesIterator );
    }

}
