

package gov.va.med.cds.hapi;


import static org.junit.Assert.fail;
import gov.va.med.cds.junit.runners.Suite;
import gov.va.med.cds.junit.runners.SuiteAwareSpringRunner;
import gov.va.med.cds.mediator.work.TemplateInformation;
import gov.va.med.cds.testharness.AbstractBaseTest;
import gov.va.med.cds.testharness.xml.XmlComparator;
import gov.va.med.cds.testharness.xml.XmlValidator;
import gov.va.med.cds.util.StreamUtil;
import gov.va.med.cds.xml.transform.XsltHelper;

import java.io.FileReader;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;


@ContextConfiguration( locations = { "classpath:config/test-message-mediator-context.xml" } )
@RunWith( SuiteAwareSpringRunner.class )
public class HL7VHIMStructureValidationTest
    extends
        AbstractBaseTest
{
    private static Log logger = LogFactory.getLog( HL7VHIMStructureValidationTest.class );

    private XsltHelper xsltHelper;

    private XmlComparator xmlComparator = new XmlComparator();

    private Map<String, TemplateInformation> sendingApplicationToTemplateInfoMap;


    @Resource
    public void setXsltHelper( XsltHelper xsltHelper )
    {
        this.xsltHelper = xsltHelper;
    }


    @Resource
    public void setSendingApplicationToTemplateInfoMap( Map<String, TemplateInformation> sendingApplicationToTemplateInfoMap )
    {
        this.sendingApplicationToTemplateInfoMap = sendingApplicationToTemplateInfoMap;
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testHDRAdasFulltoVHIMConversion( )
    {
        String inputFileName = "src/test/resources/hl7-er7/hdradas-full.txt";
        String controlFileName = "src/test/resources/hl7-vhim/expected/hdradas-full.xml";

        try
        {
            transformAndValidate( inputFileName, controlFileName, "AllergyAssessmentCreateOrUpdate40060" );
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            fail( "testHDRAdasFulltoVHIMConversion Failed.\n" + e.toString() );
        }
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testHDRAlgyFulltoVHIMConversion( )
    {
        String inputFileName = "src/test/resources/hl7-er7/hdralgy-full.txt";
        String controlFileName = "src/test/resources/hl7-vhim/expected/hdralgy-full.xml";

        try
        {
            transformAndValidate( inputFileName, controlFileName, "IntoleranceConditionCreateOrUpdate40060" );
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            fail( "testHDRAlgyFulltoVHIMConversion Failed.\n" + e.toString() );
        }
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testHDRPparFulltoVHIMConversion( )
    {
        String inputFileName = "src/test/resources/hl7-er7/hdrppar-full.txt";
        String controlFileName = "src/test/resources/hl7-vhim/expected/hdrppar-full.xml";

        try
        {
            transformAndValidate( inputFileName, controlFileName, "PharmacyCreateOrUpdate40060" );
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            fail( "testHDRPparFulltoVHIMConversion Failed.\n" + e.toString() );
        }
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testHDRVtlsHthFulltoVHIMConversion( )
    {
        String inputFileName = "src/test/resources/hl7-er7/hdrvtls_hth-full.txt";
        String controlFileName = "src/test/resources/hl7-vhim/expected/hdrvtls_hth-full.xml";

        try
        {
            transformAndValidate( inputFileName, controlFileName, "VitalsignsCreateOrUpdate40060" );
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            fail( "testHDRVtlsHthFulltoVHIMConversion Failed.\n" + e.toString() );
        }
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testHDRVtlsFulltoVHIMConversion( )
    {
        String inputFileName = "src/test/resources/hl7-er7/hdrvtls-full.txt";
        String controlFileName = "src/test/resources/hl7-vhim/expected/hdrvtls-full.xml";

        try
        {
            transformAndValidate( inputFileName, controlFileName, "VitalsignsCreateOrUpdate40060" );
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            fail( "testHDRVtlsFulltoVHIMConversion Failed.\n" + e.toString() );
        }
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testHDRAlgyCDSDatatoVHIMConversion( )
    {
        String inputFileName = "src/test/resources/hl7-er7/hdralgy_cds_data.txt";
        String controlFileName = "src/test/resources/hl7-vhim/expected/hdralgy_cds_data.xml";

        try
        {
            transformAndValidate( inputFileName, controlFileName, "IntoleranceConditionCreateOrUpdate40060" );
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            fail( "testHDRAlgyCDSDatatoVHIMConversion Failed.\n" + e.toString() );
        }
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testHDRPresCDSDatatoVHIMConversion( )
    {
        String inputFileName = "src/test/resources/hl7-er7/hdrpres_cds_data.txt";
        String controlFileName = "src/test/resources/hl7-vhim/expected/hdrpres_cds_data.xml";

        try
        {
            transformAndValidate( inputFileName, controlFileName, "PharmacyCreateOrUpdate40060" );
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            fail( "testHDRPresCDSDatatoVHIMConversion Failed.\n" + e.toString() );
        }
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testHDRPrefCHDRCDSDatatoVHIMConversion( )
    {
        String inputFileName = "src/test/resources/hl7-er7/hdrpref_chdr.txt";
        String controlFileName = "src/test/resources/hl7-vhim/expected/hdrpref_chdr.xml";

        try
        {
            transformAndValidate( inputFileName, controlFileName, "PharmacyCreateOrUpdate40060" );
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            fail( "testHDRPrefCHDRCDSDatatoVHIMConversion Failed.\n" + e.toString() );
        }
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testHDRPresVistaDatatoVHIMConversion( )
    {
        String inputFileName = "src/test/resources/hl7-er7/hdrpres-vista-full.txt";
        String controlFileName = "src/test/resources/hl7-vhim/expected/hdrpres-vista-full.xml";

        try
        {
            transformAndValidate( inputFileName, controlFileName, "PharmacyCreateOrUpdate40060" );
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            fail( "testHDRPresVistaDatatoVHIMConversion Failed.\n" + e.toString() );
        }
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testHDRVtlsCDSDatatoVHIMConversion( )
    {
        String inputFileName = "src/test/resources/hl7-er7/hdrvtls_cds_data.txt";
        String controlFileName = "src/test/resources/hl7-vhim/expected/hdrvtls_cds_data.xml";

        try
        {
            transformAndValidate( inputFileName, controlFileName, "VitalsignsCreateOrUpdate40060" );
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            fail( "testHDRVtlsCDSDatatoVHIMConversion Failed.\n" + e.toString() );
        }
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void testHDRVtlsHthCDSDatatoVHIMConversion( )
    {
        String inputFileName = "src/test/resources/hl7-er7/hdrvtls_hth_cds_data.txt";
        String controlFileName = "src/test/resources/hl7-vhim/expected/hdrvtls_hth_cds_data.xml";

        try
        {
            transformAndValidate( inputFileName, controlFileName, "VitalsignsCreateOrUpdate40060" );
        }
        catch ( Exception e )
        {
            e.printStackTrace();
            fail( "testHDRVtlsHthCDSDatatoVHIMConversion Failed.\n" + e.toString() );
        }
    }


    private void transformAndValidate( String inputFileName, String controlFileName, String templateId )
        throws Exception
    {
        String hl7Message = StreamUtil.streamAsString( new FileReader( inputFileName ) );
        String controlXml = StreamUtil.streamAsString( new FileReader( controlFileName ) );

        HL7SupportInterface hl7Support = HL7SupportHAPI.createTranslationSupport( hl7Message );
        String sourceHl7Xml = hl7Support.toXml();
        String resultXml = xsltHelper.transformMessageAsString( sourceHl7Xml, this.sendingApplicationToTemplateInfoMap.get(
                        hl7Support.getSendingApplication() ).getStylesheet() );

        XmlValidator.validateXml( resultXml, templateId );
        logger.debug( resultXml );

        xmlComparator.assertXMLSimilar( resultXml, controlXml );
    }

}
