

package gov.va.med.cds.client.functional.vhim400;


import static gov.va.med.cds.testharness.xml.Assert.assertXmlSimilar;
import static org.junit.Assert.assertTrue;
import gov.va.med.cds.client.functional.AbstractDataGeneratorValidatorTest;
import gov.va.med.cds.clinicaldata.vhim400.ClinicalDataResponse400;
import gov.va.med.cds.junit.runners.Suite;
import gov.va.med.cds.junit.runners.SuiteAwareSpringRunner;
import gov.va.med.cds.testharness.sql.ExecuteException;
import gov.va.med.cds.testharness.vhim400.TemplateIdHelper;
import gov.va.med.cds.testharness.vhim400.builders.FilterBuilder;
import gov.va.med.cds.testharness.xml.Assert;
import gov.va.med.cds.testharness.xml.XmlCompareException;
import gov.va.med.cds.testharness.xml.XmlValidationException;
import gov.va.med.cds.testharness.xml.XmlValidator;
import gov.va.med.cds.util.StreamUtil;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;

import org.dom4j.DocumentException;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.test.context.ContextConfiguration;


@RunWith( SuiteAwareSpringRunner.class )
@ContextConfiguration( locations = { "classpath:gov/va/med/cds/client/functional/vhim400/restClientTestContext.xml",
                "classpath:gov/va/med/cds/client/functional/testDataGeneratorContext.xml" } )
/*
 * This class is responsible for running REST tests.
 */
public class RestClientTest
    extends
        AbstractDataGeneratorValidatorTest
{
    @Autowired
    private String getIsAliveURL;

    @Autowired
    private String postURL;

    @Autowired
    private String postDeleteURL;

    @Autowired
    private String getURL;

    private static final String Vista_SiteId_580 = "580";
    private static final String Vista_SiteId_578 = "578";
    
    private static String XPATH_DRUGCLASS = "//drugClass";
    private static String XPATH_DRUGINGREDIENT = "//drugIngredient";
    private static String XPATH_GMRALLERGYAGENT = "//gmrAllergyAgent";
    private static String XPATH_FACILITYIDENTIIFER = "//facilityIdentifier";
    private static String XPATH_REACTION = "//reaction";
    private static String XPATH_INFORMATION_SOURCE_CATEGORY = "//informationSourceCategory";
    protected static String XPATH_SEVERITY_VALUE_CODE = "//severity/value/code";
    protected static String XPATH_SEVERITY_VALUE_DISPLAYTEXT = "//severity/value/displayText";
    protected static String XPATH_SEVERITY_VALUE_CODINGSYSTEM = "//severity/value/codingSystem";

    private static String XPATH_REFILLDISPENSES = "//refillDispense";
    private static String XPATH_ORIGINALDISPENSES = "//originalDispense";
    private static String XPATH_NUMBEROFREFILLSAUTHORIZED = "//numberOfRefillsAuthorized";
    private static String XPATH_SIG = "//sig";

    protected static String XPATH_MECHANISM_CODE = "//mechanism/code";
    protected static String XPATH_MECHANISM_DISPLAYTEXT = "//mechanism/displayText";
    protected static String XPATH_MECHANISM_CODINGSYSTEM = "//mechanism/codingSystem";
    protected static String XPATH_ALLERGY_TYPE_CODE = "//allergyType/code";
    protected static String XPATH_ALLERGY_TYPE_DISPLAYTEXT = "//allergyType/displayText";
    protected static String XPATH_ALLERGY_TYPE_CODINGSYSTEM = "//allergyType/codingSystem";
    protected static String XPATH_VERIFIED = "//verified";
    protected static String XPATH_AUTHOR_TIME = "//author/time/literal";
    protected static String XPATH_AUTHOR_FAMILY_NAME = "//author/practitioner/name/family";
    protected static String XPATH_AUTHOR_GIVEN_NAME = "//author/practitioner/name/given";
    protected static String XPATH_ASSESSMENT_VALUE_CODE = "//assessmentValue/code";
    protected static String XPATH_ASSESSMENT_VALUE_CODINGSYSTEM = "//assessmentValue/codingSystem";
    protected static String XPATH_ASSESSMENT_VALUE_DISPLAYTEXT = "//assessmentValue/displayText";
    protected static String XPATH_AGENT_CODE = "//agent/code";

    @Autowired
    protected ClinicalDataResponse400 clinicalDataResponse400;

  //Marking all test reading RDI data from VISTA as broken as we are currently not reading rdi data from vista
    @Test
    @Suite( groups = "brokentest" )
    public void testIsAlive( )
        throws IOException,
            XmlCompareException,
            TransformerException,
            ExecuteException,
            XmlValidationException
    {
  
        URL url = new URL( getIsAliveURL );
        HttpURLConnection conn = ( HttpURLConnection )url.openConnection();

        conn.setRequestMethod( "GET" );
        conn.setDoOutput( true );
        conn.connect();
        // Get the read response
        BufferedReader rd = new BufferedReader( new InputStreamReader( conn.getInputStream() ) );
        String readResult = new String();
        String line = null;
        while ( ( line = rd.readLine() ) != null )
        {
            readResult = readResult.concat( line );
        }

        rd.close();
        conn.disconnect();
        Assert.assertNotNull( readResult );
        assertTrue( readResult.contains( "true" ) );
        return;
    }
    

    @Test
    @Suite( groups = "brokentest" )
    public void testReadClinicalData40010( )
        throws MalformedURLException,
            IOException,
            TransformerConfigurationException,
            XmlValidationException,
            DocumentException
    {

        String readTemplateId = TemplateIdHelper.RDI_INTOLERANCE_CONDITION_PHARMACY_READ_TEMPLATE_ID;
        String filterId = TemplateIdHelper.RDI_IC_RX_CANNED_FILTER_ID;

        String expectedReadResultRDIIntoleranceConditionPharmacyRead40010 = StreamUtil.resourceToString( new FileSystemResource( new File(
                        "src/test/resources/AbstractClientTest/testRdi/readResultRDIIntoleranceConditionPharmacyRead40010.xml" ) ) );

        String[] vistaPatient578 = { "USVHA", Vista_SiteId_578, "1" };
        String[] hdrPatient5000 = { "USVHA", "605", "test_sourceid_5000" };
        String[] hdrPatient10000 = { "USDOD", "200CH", "test_sourceid_10000" };
        String[][] patientIdentifiers = { vistaPatient578, hdrPatient5000, hdrPatient10000 };
        List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

        Map<String, String> entryPointFilterForIntoleranceCondition = new HashMap<String, String>();
        entryPointFilterForIntoleranceCondition.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "IntoleranceCondition" );
        entryPointFilterForIntoleranceCondition.put( FilterBuilder.QUERY_NAME_KEY, "IC-Standardized" );

        Map<String, String> entryPointFilterMapForOutpatientMedicationPromise = new HashMap<String, String>();
        entryPointFilterMapForOutpatientMedicationPromise.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "OutpatientMedicationPromise" );
        entryPointFilterMapForOutpatientMedicationPromise.put( FilterBuilder.QUERY_NAME_KEY, "OMP-Standardized" );
        entryPointFilterMapForOutpatientMedicationPromise.put( FilterBuilder.START_DATE_KEY, "2007-01-01" );
        entryPointFilterMapForOutpatientMedicationPromise.put( FilterBuilder.END_DATE_KEY, "2007-12-31" );

        List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
        entryPointFilterMaps.add( entryPointFilterForIntoleranceCondition );
        entryPointFilterMaps.add( entryPointFilterMapForOutpatientMedicationPromise );

        String readFilter = dataGenerator.createFilterWithResolvedIdentifiers( filterId, entryPointFilterMaps, resolvedPatients );

        URL url;
        url = new URL( getURL + "?&templateId=" + TemplateIdHelper.RDI_INTOLERANCE_CONDITION_PHARMACY_READ_TEMPLATE_ID + "&filterRequest="
                        + readFilter + "&filterId=" + TemplateIdHelper.RDI_IC_RX_CANNED_FILTER_ID + "&requestId="
                        + TemplateIdHelper.getUniqueIdentifier() + "&facilityId=552" );

        HttpURLConnection conn = ( HttpURLConnection )url.openConnection();
        conn.setRequestMethod( "GET" );
        conn.setDoOutput( true );
        conn.connect();

        // Get the read response
        BufferedReader rd = new BufferedReader( new InputStreamReader( conn.getInputStream() ) );
        String line = null;
        String readRdiResult = new String();
        while ( ( line = rd.readLine() ) != null )
        {
            readRdiResult = readRdiResult.concat( line );
        }

        rd.close();
        conn.disconnect();
        
        assertTrue( !readRdiResult.contains( "<errorSection>" ) );
        XmlValidator.validateXml( readRdiResult, readTemplateId );
        assertXmlSimilar( detachNodesFromReadResult( readRdiResult, clinicalDataResponse400 ),
                        detachNodesFromReadResult( expectedReadResultRDIIntoleranceConditionPharmacyRead40010, clinicalDataResponse400 ) );
    }


    @Test
    @Suite( groups = "brokentest" )
    public void testReadClinicalData40011( )
        throws MalformedURLException,
            IOException,
            TransformerConfigurationException,
            XmlValidationException,
            DocumentException
    {

        String readTemplateId = TemplateIdHelper.RDI_INTOLERANCE_CONDITION_PHARMACY_READ_TEMPLATE_ID_40011;
        String filterId = TemplateIdHelper.RDI_IC_RX_CANNED_FILTER_ID;

        String expectedReadResultRDIIntoleranceConditionPharmacyRead40010 = StreamUtil.resourceToString( new FileSystemResource( new File(
                        "src/test/resources/AbstractClientTest/testRdi/readResultRDIIntoleranceConditionPharmacyRead40011.xml" ) ) );

        String[] vistaPatient578 = { "USVHA", Vista_SiteId_578, "1" };
        String[] hdrPatient5000 = { "USVHA", "605", "test_sourceid_5000" };
        String[] hdrPatient10000 = { "USDOD", "200CH", "test_sourceid_10000" };
        String[][] patientIdentifiers = { vistaPatient578, hdrPatient5000, hdrPatient10000 };
        List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );
		
        Map<String, String> entryPointFilterForIntoleranceCondition = new HashMap<String, String>();
        entryPointFilterForIntoleranceCondition.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "IntoleranceCondition" );
        entryPointFilterForIntoleranceCondition.put( FilterBuilder.QUERY_NAME_KEY, "IC-Standardized" );
        
        Map<String, String> entryPointFilterMapForOutpatientMedicationPromise = new HashMap<String, String>();
        entryPointFilterMapForOutpatientMedicationPromise.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "OutpatientMedicationPromise" );
        entryPointFilterMapForOutpatientMedicationPromise.put( FilterBuilder.QUERY_NAME_KEY, "OMP-Standardized" );
        entryPointFilterMapForOutpatientMedicationPromise.put( FilterBuilder.START_DATE_KEY, "2007-01-01" );
        entryPointFilterMapForOutpatientMedicationPromise.put( FilterBuilder.END_DATE_KEY, "2007-12-31" );
        
        List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
        entryPointFilterMaps.add( entryPointFilterForIntoleranceCondition );
        entryPointFilterMaps.add( entryPointFilterMapForOutpatientMedicationPromise );

        String readFilter = dataGenerator.createFilterWithResolvedIdentifiers( filterId, entryPointFilterMaps, resolvedPatients );

        URL url;
        url = new URL( getURL + "?templateId=" + TemplateIdHelper.RDI_INTOLERANCE_CONDITION_PHARMACY_READ_TEMPLATE_ID_40011 + "&filterRequest="
                        + readFilter + "&filterId=" + TemplateIdHelper.RDI_IC_RX_CANNED_FILTER_ID + "&requestId="
                        + TemplateIdHelper.getUniqueIdentifier() + "&facilityId=552" );

        HttpURLConnection conn = ( HttpURLConnection )url.openConnection();
        conn.setRequestMethod( "GET" );
        conn.setDoOutput( true );
        conn.connect();

        // Get the read response
        BufferedReader rd = new BufferedReader( new InputStreamReader( conn.getInputStream() ) );
        String line = null;
        String readRdiResult = new String();
        while ( ( line = rd.readLine() ) != null )
        {
            readRdiResult = readRdiResult.concat( line );
        }

        rd.close();
        conn.disconnect();
	      
        assertTrue( !readRdiResult.contains( "<errorSection>" ) );
        XmlValidator.validateXml( readRdiResult, readTemplateId );
        assertXmlSimilar( detachNodesFromReadResult( readRdiResult, clinicalDataResponse400 ),
                        detachNodesFromReadResult( expectedReadResultRDIIntoleranceConditionPharmacyRead40010, clinicalDataResponse400 ) );
    }


    @Test
    @Suite( groups = "brokenest" )
    public void testReadClinicalData40012( )
        throws MalformedURLException,
            IOException,
            TransformerConfigurationException,
            XmlValidationException,
            DocumentException
    {

        String readTemplateId = TemplateIdHelper.RDI_INTOLERANCE_CONDITION_PHARMACY_READ_TEMPLATE_ID_40012;
        String filterId = TemplateIdHelper.RDI_IC_RX_CANNED_FILTER_ID;

        String expectedReadResultRDIIntoleranceConditionPharmacyRead40012 = StreamUtil.resourceToString( new FileSystemResource( new File(
                        "src/test/resources/AbstractClientTest/testRdi/readResultRDIIntoleranceConditionPharmacyRead40012.xml" ) ) );

        String[] vistaPatient578 = { "USVHA", Vista_SiteId_578, "1" };
        String[] hdrPatient5000 = { "USVHA", "605", "test_sourceid_5000" };
        String[] hdrPatient10000 = { "USDOD", "200CH", "test_sourceid_10000" };
        String[][] patientIdentifiers = { vistaPatient578, hdrPatient5000, hdrPatient10000 };
        List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

        Map<String, String> entryPointFilterForIntoleranceCondition = new HashMap<String, String>();
        entryPointFilterForIntoleranceCondition.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "IntoleranceCondition" );
        entryPointFilterForIntoleranceCondition.put( FilterBuilder.QUERY_NAME_KEY, "IC-Standardized" );

        Map<String, String> entryPointFilterMapForOutpatientMedicationPromise = new HashMap<String, String>();
        entryPointFilterMapForOutpatientMedicationPromise.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "OutpatientMedicationPromise" );
        entryPointFilterMapForOutpatientMedicationPromise.put( FilterBuilder.QUERY_NAME_KEY, "OMP-Standardized" );
        entryPointFilterMapForOutpatientMedicationPromise.put( FilterBuilder.START_DATE_KEY, "2007-01-01" );
        entryPointFilterMapForOutpatientMedicationPromise.put( FilterBuilder.END_DATE_KEY, "2007-12-31" );

        List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
        entryPointFilterMaps.add( entryPointFilterForIntoleranceCondition );
        entryPointFilterMaps.add( entryPointFilterMapForOutpatientMedicationPromise );

        String readFilter = dataGenerator.createFilterWithResolvedIdentifiers( filterId, entryPointFilterMaps, resolvedPatients );

        URL url;
        url = new URL( getURL + "?&templateId=" + TemplateIdHelper.RDI_INTOLERANCE_CONDITION_PHARMACY_READ_TEMPLATE_ID_40012 + "&filterRequest="
                        + readFilter + "&filterId=" + TemplateIdHelper.RDI_IC_RX_CANNED_FILTER_ID + "&requestId="
                        + TemplateIdHelper.getUniqueIdentifier() + "&facilityId=552" );

        HttpURLConnection conn = ( HttpURLConnection )url.openConnection();
        conn.setRequestMethod( "GET" );
        conn.setDoOutput( true );
        conn.connect();

        // Get the read response
        BufferedReader rd = new BufferedReader( new InputStreamReader( conn.getInputStream() ) );
        String line = null;
        String readRdiResult = new String();
        while ( ( line = rd.readLine() ) != null )
        {
            readRdiResult = readRdiResult.concat( line );
        }
        
        rd.close();
        conn.disconnect();
	
        assertTrue( !readRdiResult.contains( "<errorSection>" ) );

        XmlValidator.validateXml( readRdiResult, readTemplateId );
        assertXmlSimilar( detachNodesFromReadResult( readRdiResult, clinicalDataResponse400 ),
                        detachNodesFromReadResult( expectedReadResultRDIIntoleranceConditionPharmacyRead40012, clinicalDataResponse400 ) );
    }


    @Test
    @Suite( groups = "brokentest" )
    public void testReadClinicalData40013( )
        throws MalformedURLException,
            IOException,
            TransformerConfigurationException,
            XmlValidationException,
            DocumentException
    {

        String readTemplateId = TemplateIdHelper.RDI_ALLERGIES_PHARMACY_READ_TEMPLATE_ID_40013;
        String filterId = TemplateIdHelper.RDI_ALLERGY_RX_FILTER_ID;

        String expectedReadResultRDIAllergiesPharmacyRead40013 = StreamUtil.resourceToString( new FileSystemResource( new File(
                        "src/test/resources/AbstractClientTest/testRdi/readResultRDIAllergiesPharmacyRead40013.xml" ) ) );

        String[] vistaPatient578 = { "USVHA", Vista_SiteId_578, "1" };
        String[] hdrPatient5000 = { "USVHA", "605", "test_sourceid_5000" };
        String[] hdrPatient10000 = { "USDOD", "200CH", "test_sourceid_10000" };
        String[] hdrPatient10000USVHA = { "USVHA", "660", "test_sourceid_10000" };
        String[][] patientIdentifiers = { vistaPatient578, hdrPatient5000, hdrPatient10000, hdrPatient10000USVHA };
        List<Map<String, String>> resolvedPatients = getResolvedPatients( patientIdentifiers );

        Map<String, String> entryPointFilterForIntoleranceCondition = new HashMap<String, String>();
        entryPointFilterForIntoleranceCondition.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "IntoleranceCondition" );
        entryPointFilterForIntoleranceCondition.put( FilterBuilder.QUERY_NAME_KEY, "IC-Standardized" );

        Map<String, String> entryPointFilterMapForOutpatientMedicationPromise = new HashMap<String, String>();
        entryPointFilterMapForOutpatientMedicationPromise.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "OutpatientMedicationPromise" );
        entryPointFilterMapForOutpatientMedicationPromise.put( FilterBuilder.QUERY_NAME_KEY, "OMP-Standardized" );
        entryPointFilterMapForOutpatientMedicationPromise.put( FilterBuilder.START_DATE_KEY, "2007-01-01" );
        entryPointFilterMapForOutpatientMedicationPromise.put( FilterBuilder.END_DATE_KEY, "2007-12-31" );
        
        Map<String, String> entryPointFilterForAllergyAssessment = new HashMap<String, String>();
        entryPointFilterForAllergyAssessment.put( FilterBuilder.DOMAIN_ENTRYPOINT_KEY, "AllergyAssessment" );
        entryPointFilterForAllergyAssessment.put( FilterBuilder.QUERY_NAME_KEY, "AA-Standardized" );

        List<Map<String, String>> entryPointFilterMaps = new ArrayList<Map<String, String>>();
        entryPointFilterMaps.add( entryPointFilterForIntoleranceCondition );
        entryPointFilterMaps.add( entryPointFilterForAllergyAssessment );
        entryPointFilterMaps.add( entryPointFilterMapForOutpatientMedicationPromise );
        

        String readFilter = dataGenerator.createFilterWithResolvedIdentifiers( filterId, entryPointFilterMaps, resolvedPatients );
          
        URL url;
        url = new URL( getURL + "?&templateId=" + TemplateIdHelper.RDI_ALLERGIES_PHARMACY_READ_TEMPLATE_ID_40013 + "&filterRequest="
                        + readFilter + "&filterId=" + TemplateIdHelper.RDI_ALLERGY_RX_FILTER_ID + "&requestId="
                        + TemplateIdHelper.getUniqueIdentifier() + "&facilityId=552" );

        HttpURLConnection conn = ( HttpURLConnection )url.openConnection();
        conn.setRequestMethod( "GET" );
        conn.setDoOutput( true );
        conn.connect();

        // Get the read response
        BufferedReader rd = new BufferedReader( new InputStreamReader( conn.getInputStream() ) );
        String line = null;
        String readRdiResult = new String();

        while ( ( line = rd.readLine() ) != null )
        {
            readRdiResult = readRdiResult.concat( line );
        }
        
        rd.close();
        conn.disconnect();
      
        assertTrue( !readRdiResult.contains( "<errorSection>" ) );
        XmlValidator.validateXml( readRdiResult, readTemplateId );
        assertXmlSimilar( detachNodesFromReadResult( readRdiResult, clinicalDataResponse400 ), 
                       detachNodesFromReadResult( expectedReadResultRDIAllergiesPharmacyRead40013, clinicalDataResponse400 ) );
    }
}
