

package gov.va.med.cds.integration.vhim400;


import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import gov.va.med.cds.integration.AbstractEndToEndReadAllergiesTest;
import gov.va.med.cds.junit.runners.Suite;
import gov.va.med.cds.junit.runners.SuiteAwareSpringRunner;
import gov.va.med.cds.testharness.vhim400.TemplateIdHelper;
import gov.va.med.cds.uniqueidentifier.UniqueIdentifier;

import org.dom4j.Document;
import org.dom4j.Element;
import org.junit.Test;
import org.junit.runner.RunWith;

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


@RunWith( SuiteAwareSpringRunner.class )
public class EndToEndReadAllergiesTest
    extends
        AbstractEndToEndReadAllergiesTest
{

    @Test
    @Suite( groups = { "checkintest" } )
    @SuppressWarnings( "unchecked" )
    public void testAllergyRead40010_SingleSite( )
        throws Exception
    {
        Map<String, String> assigningFacilityAndPatientIdentityMap = new HashMap<String, String>();
        assigningFacilityAndPatientIdentityMap.put( ASSIGNINGFACILITY1, PATIENTIDENTITY1 );

        Map<String, String> entryPointMap = new HashMap<String, String>();
        entryPointMap.put( "ID_1", "AllergyAssessment" );
        entryPointMap.put( "ID_2", "IntoleranceCondition" );

        String filterXml = createAllergiesSinglePatientMulitEntryPointFilter( assigningFacilityAndPatientIdentityMap, entryPointMap, null, null,
                        ASSIGNINGAUTHORITY, TemplateIdHelper.ALLERGY_SINGLE_PATIENT_ALL_DATA_FILTER, null );

        Document clinicalDataDocument = readAndAssertDomainData( assigningFacilityAndPatientIdentityMap, getAllergiesReadTemplateID(), filterXml,
                        TemplateIdHelper.ALLERGY_SINGLE_PATIENT_ALL_DATA_FILTER, getAllergyAssessmentsEntryPointXpath() );
        
        List<Element> resultsResolvedIdentifiersList = clinicalDataDocument.selectNodes( XPATH_IDENTIFIERS );
        assertNotNull( resultsResolvedIdentifiersList );
        assertTrue( resultsResolvedIdentifiersList.size() == assigningFacilityAndPatientIdentityMap.size() );
    }


    @Test
    @Suite( groups = { "checkintest" } )
    @SuppressWarnings( "unchecked" )
    public void testAllergyAssessmentRead40010_SingleSite( )
        throws Exception
    {
        Map<String, String> assigningFacilityAndPatientIdentityMap = new HashMap<String, String>();
        assigningFacilityAndPatientIdentityMap.put( ASSIGNINGFACILITY1, PATIENTIDENTITY1 );

        String filterXml = createAllergiesSinglePatientListDataFilter( assigningFacilityAndPatientIdentityMap, "AllergyAssessment",
                        ASSIGNINGAUTHORITY, TemplateIdHelper.AA_SINGLE_PATIENT_ALL_DATA_FILTER, null, null );

        Document clinicalDataDocument = readAndAssertDomainData( assigningFacilityAndPatientIdentityMap, getAlleryAssessmentsReadTemplateID(),
                        filterXml, TemplateIdHelper.AA_SINGLE_PATIENT_ALL_DATA_FILTER, getAllergyAssessmentsEntryPointXpath() );

        List<Element> resultsResolvedIdentifiersList = clinicalDataDocument.selectNodes( XPATH_IDENTIFIERS );
        assertNotNull( resultsResolvedIdentifiersList );
        assertTrue( resultsResolvedIdentifiersList.size() == assigningFacilityAndPatientIdentityMap.size() );
    }


   @Test
    @Suite( groups = { "brokentest" } )
    @SuppressWarnings( "unchecked" )
    public void testVWAllergiesRead40010_SingleSite( )
        throws Exception
    {
        Map<String, String> assigningFacilityAndPatientIdentityMap = new HashMap<String, String>();
        assigningFacilityAndPatientIdentityMap.put( ASSIGNINGFACILITY1, PATIENTIDENTITY1 );

        Map<String, String> entryPointMap = new HashMap<String, String>();
        entryPointMap.put( "ID_1", "AllergyAssessment" );
        entryPointMap.put( "ID_2", "IntoleranceCondition" );

        Map<String, String> xpathMap = new HashMap<String, String>();
        xpathMap.put( "ID_1", "allergyAssessments[status != 'E']" );
        xpathMap.put( "ID_2", "intoleranceConditions[status != 'E']" );

        String filterXml = createAllergiesSinglePatientMulitEntryPointFilter( assigningFacilityAndPatientIdentityMap, entryPointMap, null, null,
                        ASSIGNINGAUTHORITY, TemplateIdHelper.VW_ALLERGY_SINGLE_PATIENT_FILTER, xpathMap );

        Document clinicalDataDocument = readAndAssertDomainData( assigningFacilityAndPatientIdentityMap, getVWAllergiesReadTemplateID(), filterXml,
                        TemplateIdHelper.VW_ALLERGY_SINGLE_PATIENT_FILTER, getIntoleranceConditionsEntryPointXpath() );

        List<Element> resultsResolvedIdentifiersList = clinicalDataDocument.selectNodes( XPATH_IDENTIFIERS );
        assertNotNull( resultsResolvedIdentifiersList );
        assertTrue( resultsResolvedIdentifiersList.size() == assigningFacilityAndPatientIdentityMap.size() );
    }
    
    @Test
    @Suite( groups = { "brokentest" } )
    @SuppressWarnings( "unchecked" )
    public void tesHdrVWAllergiesRead40010( )
        throws Exception
    {
        Map<String, String> assigningFacilityAndPatientIdentityMap = new HashMap<String, String>();
        assigningFacilityAndPatientIdentityMap.put( ASSIGNING_FACILITY_HDR, PATIENT_IDENTITY_HDR );

        Map<String, String> entryPointMap = new HashMap<String, String>();
        entryPointMap.put( "ID_1", "AllergyAssessment" );
        entryPointMap.put( "ID_2", "IntoleranceCondition" );

        Map<String, String> xpathMap = new HashMap<String, String>();
        xpathMap.put( "ID_1", "allergyAssessments[status != 'E']" );
        xpathMap.put( "ID_2", "intoleranceConditions[status != 'E']" );

        String filterXml = createAllergiesSinglePatientMulitEntryPointFilter( assigningFacilityAndPatientIdentityMap, entryPointMap, null, null,
        		ASSIGNINGAUTHORITY_DOD, TemplateIdHelper.VW_ALLERGY_SINGLE_PATIENT_FILTER, xpathMap );

        Document clinicalDataDocument = readAndAssertDomainData( assigningFacilityAndPatientIdentityMap, getVWAllergiesReadTemplateID(), filterXml,
                        TemplateIdHelper.VW_ALLERGY_SINGLE_PATIENT_FILTER, getIntoleranceConditionsEntryPointXpath() );

        List<Element> resultsResolvedIdentifiersList = clinicalDataDocument.selectNodes( XPATH_IDENTIFIERS );
        assertNotNull( resultsResolvedIdentifiersList );
        assertTrue( resultsResolvedIdentifiersList.size() == assigningFacilityAndPatientIdentityMap.size() );
    }



    @Test
    @Suite( groups = { "checkintest" } )
    @SuppressWarnings( "unchecked" )
    public void testIntoleranceConditionRead40010_SingleSite( )
        throws Exception
    {
        Map<String, String> assigningFacilityAndPatientIdentityMap = new HashMap<String, String>();
        assigningFacilityAndPatientIdentityMap.put( ASSIGNINGFACILITY1, PATIENTIDENTITY1 );

        String filterXml = createAllergiesSinglePatientListDataFilter( assigningFacilityAndPatientIdentityMap, "IntoleranceCondition",
                        ASSIGNINGAUTHORITY, TemplateIdHelper.IC_SINGLE_PATIENT_ALL_DATA_FILTER, null, null );

        Document clinicalDataDocument = readAndAssertDomainData( assigningFacilityAndPatientIdentityMap, getIntoleranceConditionsReadTemplateID(),
                        filterXml, TemplateIdHelper.IC_SINGLE_PATIENT_ALL_DATA_FILTER, getIntoleranceConditionsEntryPointXpath() );

        List<Element> resultsResolvedIdentifiersList = clinicalDataDocument.selectNodes( XPATH_IDENTIFIERS );
        assertNotNull( resultsResolvedIdentifiersList );
        assertTrue( resultsResolvedIdentifiersList.size() == assigningFacilityAndPatientIdentityMap.size() );
    }


    @Test
    @Suite( groups = { "checkintest" } )
    @SuppressWarnings( "unchecked" )
    public void testIntoleranceConditionReducedRead40011_SingleSite( )
        throws Exception
    {
        Map<String, String> assigningFacilityAndPatientIdentityMap = new HashMap<String, String>();
        assigningFacilityAndPatientIdentityMap.put( ASSIGNINGFACILITY1, PATIENTIDENTITY1 );

        String filterXml = createAllergiesSinglePatientListDataFilter( assigningFacilityAndPatientIdentityMap, "IntoleranceCondition",
                        ASSIGNINGAUTHORITY, TemplateIdHelper.IC_SINGLE_PATIENT_ALL_DATA_FILTER, null, null );

        Document clinicalDataDocument = readAndAssertDomainData( assigningFacilityAndPatientIdentityMap,
                        getIntoleranceConditionsReducedReadTemplateID(), filterXml, TemplateIdHelper.IC_SINGLE_PATIENT_ALL_DATA_FILTER,
                        getIntoleranceConditionsEntryPointXpath() );

        List<Element> resultsResolvedIdentifiersList = clinicalDataDocument.selectNodes( XPATH_IDENTIFIERS );
        assertNotNull( resultsResolvedIdentifiersList );
        assertTrue( resultsResolvedIdentifiersList.size() == assigningFacilityAndPatientIdentityMap.size() );
    }


    @Test
    @Suite( groups = { "checkintest" } )
    @SuppressWarnings( "unchecked" )
    public void testVWIntoleranceConditionRead40010_SingleSite( )
        throws Exception
    {
        Map<String, String> assigningFacilityAndPatientIdentityMap = new HashMap<String, String>();
        assigningFacilityAndPatientIdentityMap.put( ASSIGNINGFACILITY1, PATIENTIDENTITY1 );

        Map<String, String> entryPointMap = new HashMap<String, String>();
        entryPointMap.put( "ID_1", "IntoleranceCondition" );

        Map<String, String> xpathMap = new HashMap<String, String>();
        xpathMap.put( "ID_1", "intoleranceConditions[status != 'E']" );

        String filterXml = createAllergiesSinglePatientMulitEntryPointFilter( assigningFacilityAndPatientIdentityMap, entryPointMap, null, null,
                        ASSIGNINGAUTHORITY, TemplateIdHelper.VW_IC_SINGLE_PATIENT_FILTER, xpathMap );

        Document clinicalDataDocument = readAndAssertDomainData( assigningFacilityAndPatientIdentityMap, getVWIntoleranceConditionsReadTemplateID(),
                        filterXml, TemplateIdHelper.VW_IC_SINGLE_PATIENT_FILTER, getIntoleranceConditionsEntryPointXpath() );

        List<Element> resultsResolvedIdentifiersList = clinicalDataDocument.selectNodes( XPATH_IDENTIFIERS );
        assertNotNull( resultsResolvedIdentifiersList );
        assertTrue( resultsResolvedIdentifiersList.size() == assigningFacilityAndPatientIdentityMap.size() );
    }


    @Test
    @Suite( groups = { "checkintest" } )
    @SuppressWarnings( "unchecked" )
    public void testMHVIntoleranceConditionRead40011_SingleSite( )
        throws Exception
    {
        Map<String, String> assigningFacilityAndPatientIdentityMap = new HashMap<String, String>();
        assigningFacilityAndPatientIdentityMap.put( ASSIGNINGFACILITY1, PATIENTIDENTITY1 );

        String filterXml = createAllergiesSinglePatientListDataFilter( assigningFacilityAndPatientIdentityMap, "IntoleranceCondition",
                        ASSIGNINGAUTHORITY, TemplateIdHelper.IC_SINGLE_PATIENT_ALL_DATA_FILTER, null, null );

        Document clinicalDataDocument = readAndAssertDomainData( assigningFacilityAndPatientIdentityMap, getMHVIntoleranceConditionsReadTemplateID(),
                        filterXml, TemplateIdHelper.IC_SINGLE_PATIENT_ALL_DATA_FILTER, getIntoleranceConditionsEntryPointXpath() );

        List<Element> resultsResolvedIdentifiersList = clinicalDataDocument.selectNodes( XPATH_IDENTIFIERS );
        assertNotNull( resultsResolvedIdentifiersList );
        assertTrue( resultsResolvedIdentifiersList.size() == assigningFacilityAndPatientIdentityMap.size() );
    }


    @SuppressWarnings( "unchecked" )
    protected Document readAndAssertDomainData( Map<String, String> assigningFacilityAndPatientIdentityMap, String templateId, String filter,
                    String filterId, String entryPointXpath )
        throws Exception
    {
        requestProcessor.setValidateReadResponseXML( true );

        Document clinicalDataDocument = requestProcessor.readClinicalData( templateId, filter, filterId, new UniqueIdentifier().toString() );
        assertNotNull( clinicalDataDocument );

        // Check for error sections
        List<Element> errorSections = clinicalDataDocument.selectNodes( XPATH_ERRORSECTION );
        assertTrue( errorSections.size() == 0 );

        // Check for domain entry point elements
        List<Element> domainElements = clinicalDataDocument.selectNodes( entryPointXpath );
        assertTrue( domainElements.size() > 0 );

        // Assert that the resolved identifier assigning facility values from the filter are in the result document
        List<Element> resultsResolvedIdentifiersList = clinicalDataDocument.selectNodes( XPATH_IDENTIFIERS );
        for ( Element resultsResolvedIdentifiers : resultsResolvedIdentifiersList )
        {
            String mapAssigningFacility = resultsResolvedIdentifiers.element( "assigningFacility" ).getText();
            assertTrue( assigningFacilityAndPatientIdentityMap.containsKey( mapAssigningFacility ) );

            String mapIdentity = assigningFacilityAndPatientIdentityMap.get( mapAssigningFacility );
            assertTrue( ( resultsResolvedIdentifiers.element( "identity" ).getText() ).equals( mapIdentity ) );
        }

        return clinicalDataDocument;
    }
}