

package gov.va.med.cds.mediator.work;


import gov.va.med.cds.audit.persistence.CdsAuditClobStore;
import gov.va.med.cds.audit.persistence.CdsAuditClobStoreInterface;
import gov.va.med.cds.hapi.HL7SupportHAPI;
import gov.va.med.cds.hapi.HL7SupportInterface;
import gov.va.med.cds.junit.runners.Suite;
import gov.va.med.cds.junit.runners.SuiteAwareRunner;
import gov.va.med.cds.util.StreamUtil;

import java.io.FileReader;

import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;


@RunWith( SuiteAwareRunner.class )
public class AuditClobWorkTest
{
    @Test
    @Suite( groups = { "checkintest" } )
    public void testDoWork( )
    {
        AuditClobWork auditClobWork = new AuditClobWork();

        String wsnMessage = "wsnMessage";
        auditClobWork.setWsnMessage( wsnMessage );

        String wsnHl7Support = "wsnHl7Support";
        auditClobWork.setWsnHl7Support( wsnHl7Support );

        String wsnPersistFlag = "persistMessage";
        auditClobWork.setWsnPersistFlag( wsnPersistFlag );
        
        String wsnTemplateInformation = "wsnTemplateInformation";
        TemplateInformation templateInformation = new TemplateInformation( "StyleSheet", "TemplateId" );
        auditClobWork.setWsnTemplateInformation( wsnTemplateInformation );

        HL7SupportInterface hL7SupportInterfaceMock = EasyMock.createMock( HL7SupportInterface.class );
        EasyMock.expect( hL7SupportInterfaceMock.getSendingFacility() ).andReturn( "SendingFacility" );
        EasyMock.expect( hL7SupportInterfaceMock.getMessageControlId() ).andReturn( "MessageControlId" );
        EasyMock.expect( hL7SupportInterfaceMock.getSendingApplication() ).andReturn( "SendingApplication" );
        EasyMock.expect( hL7SupportInterfaceMock.getMessageDateTime() ).andReturn( "MessageDateTime" );

        WorkStateInterface workStateMock = EasyMock.createMock( WorkStateInterface.class );
        EasyMock.expect( workStateMock.locateWorkState( wsnPersistFlag ) ).andReturn( Boolean.TRUE );
        EasyMock.expect( workStateMock.locateWorkState( wsnMessage ) ).andReturn( "hl7Message" );
        EasyMock.expect( workStateMock.locateWorkState( wsnHl7Support ) ).andReturn( hL7SupportInterfaceMock );
        EasyMock.expect( workStateMock.locateWorkState( wsnTemplateInformation ) ).andReturn( templateInformation );

        CdsAuditClobStoreInterface cdsAuditClobStoreMock = EasyMock.createNiceMock( CdsAuditClobStoreInterface.class );
        auditClobWork.setCdsAuditClobStore( cdsAuditClobStoreMock );
        EasyMock.replay( new Object[] { workStateMock, hL7SupportInterfaceMock, cdsAuditClobStoreMock } );

        auditClobWork.doWork( workStateMock );
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testDoWorkWithRealHL7_Message( )
        throws Exception
    {
        AuditClobWork auditClobWork = new AuditClobWork()
        {
            @Override
            public void persistCdsAuditClob( CdsAuditClobStore auditClob )
            {
                // Bug fix : CQ17837.
                // Verify that message type is set to msh-3 field from the hl7 message
                Assert.assertEquals( "HDRALGY", auditClob.getMessageType() );

                // Verify that other fields set as expected
                Assert.assertEquals( "DNS   .DNS      URL        ", auditClob.getFacilityId() );
                Assert.assertEquals( "20020921133629-0500", auditClob.getMessageDateTime() );
                Assert.assertEquals( "500167099", auditClob.getRequestId() );
                Assert.assertNull( "Audit id should be null for new record, Hibernate will set it", auditClob.getAuditId() );

                super.persistCdsAuditClob( auditClob );
            }
        };

        String wsnPersistFlag = "persistMessage";
        String wsnMessage = "wsnMessage";
        String wsnHl7Support = "wsnHl7Support";
        String hl7Message = "hl7Message";
        String wsnTemplateInformation = "wsnTemplateInformation";
        TemplateInformation templateInformation = new TemplateInformation( "StyleSheet", "TemplateId" );
        auditClobWork.setWsnTemplateInformation( wsnTemplateInformation );

        auditClobWork.setWsnMessage( wsnMessage );
        auditClobWork.setWsnHl7Support( wsnHl7Support );
        auditClobWork.setWsnPersistFlag( wsnPersistFlag );

        // Get a real hl7 allergy message from resource file. 
        String message = StreamUtil.streamAsString( new FileReader( "./src/test/resources/hl7-er7/hdralgy-full.txt" ) );
        HL7SupportInterface hL7HAPISupport = HL7SupportHAPI.createTranslationSupport( message );

        CdsAuditClobStoreInterface cdsAuditClobStoreMock = EasyMock.createMock( CdsAuditClobStoreInterface.class );
        auditClobWork.setCdsAuditClobStore( cdsAuditClobStoreMock );

        WorkStateInterface workStateMock = EasyMock.createMock( WorkStateInterface.class );
        EasyMock.expect( workStateMock.locateWorkState( wsnPersistFlag ) ).andReturn( Boolean.TRUE );
        EasyMock.expect( workStateMock.locateWorkState( "wsnMessage" ) ).andReturn( hl7Message );
        EasyMock.expect( workStateMock.locateWorkState( wsnHl7Support ) ).andReturn( hL7HAPISupport );
        EasyMock.expect( workStateMock.locateWorkState( wsnTemplateInformation ) ).andReturn( templateInformation );
        cdsAuditClobStoreMock.persistCdsAuditClob( EasyMock.isA( CdsAuditClobStore.class ) );

        EasyMock.replay( new Object[] { workStateMock, cdsAuditClobStoreMock } );

        auditClobWork.doWork( workStateMock );
        EasyMock.verify( new Object[] { workStateMock, cdsAuditClobStoreMock } );
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testDoWorkWithFailure( )
        throws Exception
    {
        AuditClobWork auditClobWork = new AuditClobWork()
        {
            @Override
            public void persistCdsAuditClob( CdsAuditClobStore auditClob )
            {
                super.persistCdsAuditClob( auditClob );
            }
        };

        RuntimeException runtimeException = new RuntimeException( "Failure Persisting Clob" );
        String wsnPersistFlag = "persistMessage";
        String wsnMessage = "wsnMessage";
        String wsnHl7Support = "wsnHl7Support";
        String hl7Message = "hl7Message";
        String wsnClobNOTPersistedFlag = "AUDIT_CLOB_NOT_PERSISTED";
        String wsnTemplateInformation = "wsnTemplateInformation";
        
        TemplateInformation templateInformation = new TemplateInformation( "StyleSheet", "TemplateId" );
        
        auditClobWork.setWsnTemplateInformation( wsnTemplateInformation );
        auditClobWork.setWsnMessage( wsnMessage );
        auditClobWork.setWsnHl7Support( wsnHl7Support );
        auditClobWork.setWsnPersistFlag( wsnPersistFlag );
        auditClobWork.setWsnClobNOTPersistedFlag( wsnClobNOTPersistedFlag );

        // Get a real hl7 allergy message from resource file. 
        String message = StreamUtil.streamAsString( new FileReader( "./src/test/resources/hl7-er7/hdralgy-full.txt" ) );
        HL7SupportInterface hL7HAPISupport = HL7SupportHAPI.createTranslationSupport( message );

        CdsAuditClobStoreInterface cdsAuditClobStoreMock = EasyMock.createMock( CdsAuditClobStoreInterface.class );
        auditClobWork.setCdsAuditClobStore( cdsAuditClobStoreMock );

        WorkStateInterface workStateMock = EasyMock.createMock( WorkStateInterface.class );
        EasyMock.expect( workStateMock.locateWorkState( wsnPersistFlag ) ).andReturn( Boolean.TRUE );
        EasyMock.expect( workStateMock.locateWorkState( "wsnMessage" ) ).andReturn( hl7Message );
        EasyMock.expect( workStateMock.locateWorkState( wsnHl7Support ) ).andReturn( hL7HAPISupport );
        EasyMock.expect( workStateMock.locateWorkState( wsnTemplateInformation ) ).andReturn( templateInformation );
        cdsAuditClobStoreMock.persistCdsAuditClob( EasyMock.isA( CdsAuditClobStore.class ) );
        EasyMock.expectLastCall().andThrow( runtimeException );

        //adding methods to verify the exception is thrown in the Worker and code is entered to register clob not persisted flag and add exception
        workStateMock.registerWorkState( wsnClobNOTPersistedFlag, true );
        workStateMock.addException( EasyMock.isA( Exception.class ) );

        EasyMock.replay( new Object[] { workStateMock, cdsAuditClobStoreMock } );

        auditClobWork.doWork( workStateMock );
        EasyMock.verify( new Object[] { workStateMock, cdsAuditClobStoreMock } );
    }

}
