

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


import static org.junit.Assert.assertNotNull;

import gov.va.med.cds.integration.AbstractEndToEndAllVistADataSourcesFailingTest;
import gov.va.med.cds.junit.runners.Suite;
import gov.va.med.cds.request.TemplateRequestProcessor;
import gov.va.med.cds.testharness.vhim400.TemplateIdHelper;
import gov.va.med.cds.testharness.vhim400.builders.FilterBuilder;
import gov.va.med.cds.uniqueidentifier.UniqueIdentifier;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.junit.Assert;
import org.junit.Test;

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


public class VistAAllDatasourcesFailingTest
    extends
        AbstractEndToEndAllVistADataSourcesFailingTest
{
    protected static final String TIU_LIST_REQUIRED_XQUERY_CRITERIA = "/referenceDate/literal descending";
    protected static String ASSIGNINGAUTHORITY = "USVHA";
    protected static String RECORDIDENTIFIER1 = "6";
    protected static String NAMESPACEID1 = "580_8925";
    protected static String XPATH_ERRORSECTION = "//errorSection";
    protected static String XPATH_DOMAINENTRYPOINT = "//clinicalDocumentEvents";
    protected TemplateRequestProcessor requestProcessor;

    private static String PATIENTIDENTITY_1 = "1";
    private static String PATIENTIDENTITY_2 = "1";
    private static String ASSIGNINGFACILITY_FAILURE_1 = "580";
    private static String ASSIGNINGFACILITY_FAILURE_2 = "578";
    private static String INVALID_ASSIGNINGFACILITY = "800";
    private static String DOCUMENT_CLASS_VALUE = "3";
    private static String[] DOCUMENT_TYPE_VALUES = {};
    private static String XPATH_ERRORSECTION_FATALERROR = "//errorSection/fatalErrors/fatalError";
    private static String XPATH_ERRORSECTION_FATALERRORCODE = "//errorSection/fatalErrors/fatalError/errorCode";
    private static final String READ_REQUEST_ALL_DATASOURCES_FAILED = "READ_REQUEST_ALL_DATASOURCES_FAILED";
    private static String XPATH_ERRORSECTION_WARNING = "//errorSection/warnings/warning";


    @SuppressWarnings( "unchecked" )
    @Test
    @Suite( groups = { "checkintest" } )
    public void testCompleteFailureListRead_AllSites( )
        throws Exception
    {
        // set to validate against schema
        requestProcessor = ( TemplateRequestProcessor )getRequestProcessor();
        requestProcessor.setValidateReadResponseXML( true );
        Document clinicalDataDocument = requestProcessor.readClinicalData( TemplateIdHelper.TIU_DOCUMENT_LIST_READ,
                        getFilterXmlForCompleteFailure_AllSites(), TemplateIdHelper.TIU_SINGLE_PATIENT_LIST_DATA_FILTER,
                        new UniqueIdentifier().toString() );
        assertNotNull( clinicalDataDocument );

        //make sure no data was read from any site...
        List<Node> clinicalDocumentNodes = clinicalDataDocument.selectNodes( XPATH_DOMAINENTRYPOINT );
        Assert.assertTrue( clinicalDocumentNodes.size() == 0 );

        //make sure we reported a fatal error for READ_REQUEST_ALL_DATA_SOURCES_FAILED        
        List<Node> fatalNodes = clinicalDataDocument.selectNodes( XPATH_ERRORSECTION_FATALERROR );
        Assert.assertTrue( fatalNodes.size() == 1 );
        Node errorCodeNode = clinicalDataDocument.selectSingleNode( XPATH_ERRORSECTION_FATALERRORCODE );
        Assert.assertTrue( errorCodeNode.getText().equals( READ_REQUEST_ALL_DATASOURCES_FAILED ) );
    }


    private String getFilterXmlForCompleteFailure_AllSites( )
    {
        Map<String, String> assigningFacilityAndPatientIdentityMap = new HashMap<String, String>();
        //success
        assigningFacilityAndPatientIdentityMap.put( ASSIGNINGFACILITY_FAILURE_1, PATIENTIDENTITY_1 );
        //failure
        assigningFacilityAndPatientIdentityMap.put( ASSIGNINGFACILITY_FAILURE_2, PATIENTIDENTITY_2 );

        String filterXml = createTiuSinglePatientListDataFilter( assigningFacilityAndPatientIdentityMap, ASSIGNINGAUTHORITY,
                        TemplateIdHelper.TIU_SINGLE_PATIENT_LIST_DATA_FILTER, DOCUMENT_CLASS_VALUE, DOCUMENT_TYPE_VALUES, null, null, null,
                        TIU_LIST_REQUIRED_XQUERY_CRITERIA );
        return filterXml;
    }


    @SuppressWarnings( "unchecked" )
    @Test
    @Suite( groups = { "checkintest" } )
    public void testExceptionsFromSitesNInvalidSiteId( )
        throws Exception
    {
        // set to validate against schema
        requestProcessor = ( TemplateRequestProcessor )getRequestProcessor();
        requestProcessor.setValidateReadResponseXML( true );
        Document clinicalDataDocument = requestProcessor.readClinicalData( TemplateIdHelper.TIU_DOCUMENT_LIST_READ,
                        getFilterXmlForExceptionsFromSitesNInvalidSiteId(), TemplateIdHelper.TIU_SINGLE_PATIENT_LIST_DATA_FILTER,
                        new UniqueIdentifier().toString() );
        assertNotNull( clinicalDataDocument );

        //make sure no data was read from any site...
        List<Node> clinicalDocumentNodes = clinicalDataDocument.selectNodes( XPATH_DOMAINENTRYPOINT );
        Assert.assertTrue( clinicalDocumentNodes.size() == 0 );

        List<Node> warningNodes = clinicalDataDocument.selectNodes( XPATH_ERRORSECTION_WARNING );
        Assert.assertTrue( warningNodes.size() == 3 );

        String responseXml = clinicalDataDocument.asXML();
        Assert.assertTrue( responseXml.contains( "<errorCode>READ_REQUEST_DATA_SOURCE_FAILURE</errorCode>" ) );
        Assert.assertTrue( responseXml.contains( "<errorCode>INVALID_ASSIGNING_FACILITIES_IN_FILTER_XML_REQUEST</errorCode>" ) );

    }


    private String getFilterXmlForExceptionsFromSitesNInvalidSiteId( )
    {
        Map<String, String> assigningFacilityAndPatientIdentityMap = new HashMap<String, String>();

        assigningFacilityAndPatientIdentityMap.put( ASSIGNINGFACILITY_FAILURE_1, PATIENTIDENTITY_1 );
        assigningFacilityAndPatientIdentityMap.put( ASSIGNINGFACILITY_FAILURE_2, PATIENTIDENTITY_2 );
        //invalid site id/assigning facility 
        assigningFacilityAndPatientIdentityMap.put( INVALID_ASSIGNINGFACILITY, PATIENTIDENTITY_2 );
        String filterXml = createTiuSinglePatientListDataFilter( assigningFacilityAndPatientIdentityMap, ASSIGNINGAUTHORITY,
                        TemplateIdHelper.TIU_SINGLE_PATIENT_LIST_DATA_FILTER, DOCUMENT_CLASS_VALUE, DOCUMENT_TYPE_VALUES, null, null, null,
                        TIU_LIST_REQUIRED_XQUERY_CRITERIA );
        return filterXml;
    }


    private String createTiuSinglePatientListDataFilter( Map<String, String> assigningFacilityAndPatientIdentityMap, String assigningAuthority,
                    String filterId, String documentClassValue, String[] documentTypeValues, String startDate, String endDate, String nationalId,
                    String xQuery )
    {
        Document filterDocument = FilterBuilder.buildEmptyFilterDocument();
        Element element = filterDocument.getRootElement();
        element.add( FilterBuilder.createFilterId( "filterId", filterId ) );
        if ( nationalId != null )
        {
            element.add( FilterBuilder.createPatientWithNationalId( "patients", nationalId, null ) );
        }
        else
        {
            element.add( FilterBuilder.createPatient( "patients", assigningAuthority, assigningFacilityAndPatientIdentityMap ) );
        }

        element.add( FilterBuilder.createEntryFilterWithAdditionalParameters( "entryPointFilter", "ClinicalDocumentEvent", startDate, endDate,
                        documentClassValue, documentTypeValues, "ID_1", xQuery ) );

        element.addAttribute( "vhimVersion", "Vhim_4_00" );
        return element.asXML();
    }

}
