

package gov.va.med.cds.template;


import static org.easymock.EasyMock.*;
import gov.va.med.cds.clinicaldata.Operation;
import gov.va.med.cds.clinicaldata.TemplateMetaDataInterface;
import gov.va.med.cds.junit.runners.Suite;
import gov.va.med.cds.junit.runners.SuiteAwareRunner;
import gov.va.med.cds.request.ValidationException;
import gov.va.med.cds.xml.schema.SchemaHelperInterface;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.validation.Validator;

import org.dom4j.DocumentHelper;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;


@RunWith( SuiteAwareRunner.class )
public class TemplateManagerTest
{
    private static Validator validator = null;
    private static TemplateMetaDataInterface metaData = null;
    private static SchemaHelperInterface schemaHelper = null;
    private static TemplateCacheInterface templateCache = null;
    private static TemplateServiceInterface templateService = null;
    private static TemplateWriteRequest templateWriteRequest = null;
    private static TemplateCachePersistenceInterface templateCachePersistence = null;

    private static Map<String, List<String>> symbolMap = new HashMap<String, List<String>>();

    private static List<String> vhimVersion = new LinkedList<String>();
    private static List<String> templateIds = new LinkedList<String>();

    private static TemplateManager templateManager = null;


    private static void initMocks( )
    {
        validator = createNiceMock( Validator.class );
        metaData = createNiceMock( TemplateMetaDataInterface.class );
        schemaHelper = createNiceMock( SchemaHelperInterface.class );
        templateCache = createNiceMock( TemplateCacheInterface.class );
        templateService = createNiceMock( TemplateServiceInterface.class );
        templateWriteRequest = createNiceMock( TemplateWriteRequest.class );
        templateCachePersistence = createNiceMock( TemplateCachePersistenceInterface.class );
    }


    @BeforeClass
    @Suite( groups = { "checkintest" } )
    public static void setUpTemplateManagerTest( )
    {
        initMocks();

        templateIds.add( "templateId" );
        vhimVersion.add( "VHIM_4_00" );
    }


    @Before
    @Suite( groups = { "checkintest" } )
    public void setUp( )
    {
        reset( templateCache, templateService, templateCachePersistence, validator, schemaHelper, metaData, templateWriteRequest );

        expect( templateService.getVhimVersions() ).andReturn( vhimVersion ).anyTimes();
        expect( templateService.getActiveTemplateIds( "VHIM_4_00" ) ).andReturn( templateIds ).anyTimes();

        expect( schemaHelper.getValidator() ).andReturn( validator ).anyTimes();
        expect( schemaHelper.getSymbolMap() ).andReturn( symbolMap ).anyTimes();

        expect( templateCache.getSchemaHelper( "templateId" ) ).andReturn( schemaHelper ).anyTimes();
        expect( templateCache.getTemplateMetaData( "templateId" ) ).andReturn( metaData ).anyTimes();
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void validateWriteRequestTest( )
        throws Exception
    {
        expect( templateWriteRequest.getOperation() ).andReturn( Operation.Create ).anyTimes();
        expect( templateWriteRequest.getRequestData() ).andReturn( "xml" ).anyTimes();
        expect( templateWriteRequest.getRequestId() ).andReturn( "requestId" ).anyTimes();
        expect( templateWriteRequest.getTemplateId() ).andReturn( "templateId" ).anyTimes();

        replay( templateCache, templateService, templateCachePersistence, validator, schemaHelper, metaData, templateWriteRequest );

        templateManager = new TemplateManager( templateService, templateCachePersistence, templateCache );
        templateManager.setTemplateCache( templateCache );
        templateManager.validateWriteRequest( templateWriteRequest );
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void validateReadTemplateIdTest( )
        throws Exception
    {
        expect( metaData.getOperation() ).andReturn( Operation.Read );

        replay( templateCache, templateService, templateCachePersistence, validator, schemaHelper, metaData, templateWriteRequest );

        templateManager = new TemplateManager( templateService, templateCachePersistence, templateCache );
        templateManager.setTemplateCache( templateCache );
        templateManager.validateReadTemplateId( "templateId" );
    }


    @Test( expected = ValidationException.class )
    @Suite( groups = { "checkintest" } )
    public void validateReadTemplateExceptionTest( )
        throws Exception
    {
        expect( metaData.getOperation() ).andReturn( Operation.Create ).anyTimes();

        replay( templateCache, templateService, templateCachePersistence, validator, schemaHelper, metaData, templateWriteRequest );

        templateManager = new TemplateManager( templateService, templateCachePersistence, templateCache );
        templateManager.validateReadTemplateId( "templateId" );
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void validateReadResponseTest( )
        throws Exception
    {
        replay( templateCache, templateService, templateCachePersistence, validator, schemaHelper, metaData, templateWriteRequest );

        templateManager = new TemplateManager( templateService, templateCachePersistence, templateCache );
        templateManager.setTemplateCache( templateCache );
        templateManager.validateReadResponse( DocumentHelper.parseText( "<xml></xml>" ), "templateId" );
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void templateManagerTest( )
        throws Exception
    {
        Set<String> set = new HashSet<String>();

        expect( templateCache.getTemplateCacheTemplateIds() ).andReturn( set );
        expect( templateCache.getTemplateCacheThreshold() ).andReturn( 2 ).anyTimes();

        replay( templateCache, templateService, templateCachePersistence, validator, schemaHelper, metaData, templateWriteRequest );

        templateManager = new TemplateManager( templateService, templateCachePersistence, templateCache );
        templateManager.getSymbolMap( "templateId" );
        templateManager.getNumberOfTemplatesLoadedIntoTemplateCache();
        templateManager.getTemplateCacheTemplateIds();
        templateManager.getTemplateCacheThreshold();
        templateManager.reinitializeTemplateCache();
        templateManager.resizeTemplateCache( 1 );
    }


    @Test( expected = TemplateMetaDataProviderException.class )
    @Suite( groups = { "checkintest" } )
    public void getTemplateMetaDataTest( )
        throws Exception
    {
        expect( templateCache.getTemplateMetaData( "templateId2" ) ).andReturn( null );
        replay( templateCache, templateService, templateCachePersistence, validator, schemaHelper, metaData, templateWriteRequest );

        templateManager = new TemplateManager( templateService, templateCachePersistence, templateCache );

        templateManager.getTemplateMetaData( "templateId2" );
    }


    @Test( expected = ValidationException.class )
    @Suite( groups = { "checkintest" } )
    public void getSchemaHelperTest( )
        throws Exception
    {
        expect( templateCache.getSchemaHelper( "templateId3" ) ).andReturn( null );
        replay( templateCache, templateService, templateCachePersistence, validator, schemaHelper, metaData, templateWriteRequest );

        templateManager = new TemplateManager( templateService, templateCachePersistence, templateCache );

        templateManager.getSchemaHelper( "templateId3" );
    }


    @Test( expected = ValidationException.class )
    @Suite( groups = { "checkintest" } )
    public void validateWriteRequestNullTest( )
        throws Exception
    {
        replay( templateCache, templateService, templateCachePersistence, validator, schemaHelper, metaData, templateWriteRequest );

        templateManager = new TemplateManager( templateService, templateCachePersistence, templateCache );

        templateManager.validateWriteRequest( null );
    }


    @Test( expected = TemplateMetaDataProviderException.class )
    @Suite( groups = { "checkintest" } )
    public void validateWriteRequestTemplateCacheExceptionTest( )
        throws Exception
    {
        expect( templateWriteRequest.getOperation() ).andReturn( Operation.Create ).anyTimes();
        expect( templateWriteRequest.getRequestData() ).andReturn( "xml" ).anyTimes();
        expect( templateWriteRequest.getRequestId() ).andReturn( "requestId" ).anyTimes();
        expect( templateWriteRequest.getTemplateId() ).andReturn( "templateId4" ).anyTimes();

        expect( templateCache.getSchemaHelper( "templateId4" ) ).andReturn( null );
        expect( templateCache.getTemplateMetaData( "templateId4" ) ).andReturn( null );
        expect( templateCache.getSchemaHelper( "templateId4" ) ).andReturn( schemaHelper );

        replay( templateCache, templateService, templateCachePersistence, validator, schemaHelper, metaData, templateWriteRequest );

        templateManager = new TemplateManager( templateService, templateCachePersistence, templateCache );

        templateManager.validateWriteRequest( templateWriteRequest );
    }

}
