

package gov.va.med.cds.integration;


import static org.junit.Assert.assertFalse;
import gov.va.med.cds.junit.runners.SuiteAwareRunner;
import gov.va.med.cds.junit.runners.Suite;
import gov.va.med.cds.request.ReadResponseInterface;
import gov.va.med.cds.request.RequestProcessorInterface;
import gov.va.med.cds.request.ResponseInterface;
import gov.va.med.cds.testharness.vhim400.TemplateIdHelper;
import gov.va.med.cds.testharness.xml.XmlCompareException;
import gov.va.med.cds.uniqueidentifier.UniqueIdentifier;

import java.io.IOException;
import java.util.Date;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.parsers.ParserConfigurationException;

import org.dom4j.Document;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xml.sax.SAXException;


/**
 * 
 * This initiates all tests through the outermost client pojo (ClinicalDataServiceSynchronous). This has the vhim
 * version agnostic functionality that is common to the vhim version specific subclasses. It will generate a vdm record
 * and save it off to the DB. Next, it will read the same record back and marshall it to XML and compare it with the
 * original vdm record. Also, does some bounds checking for persistence filters. It doesn't test historical.
 * 
 * TODO: The first pass refactoring of moving vhim version dependencies to subclasses is done. The second pass
 * refactoring of keeping common code in one place is NOT done.
 * 
 */
@RunWith( SuiteAwareRunner.class )
public abstract class AbstractEndToEndCRUADAutoWiredTest
    extends
        AbstractEndToEndTest
{
    protected static final String INTOLERANCE_CONDITION = "Intolerance Condition";
    protected static final String ALLERGY_ASSESSEMENT = "Allergy Assessement";
    protected static final String VITAL_OBSERVATION_EVENT = "Vital Observation Event";
    protected static final String OUTPATIENT_MEDICATION_PROMISE = "Outpatient Medication Promise";
    protected static final String LAB_PROMISE = "Lab Promise";


    /**
     * Tests CRUD of Allergy assesssment
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testAllergyAssessmentCreateReadXmlCompareDelete( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createAllergyAssessmentXml( requestId );

        // persist
        createAllergyAssessment( createXml, requestId );

        // read
        String readResultXml = readAllergyAssessment( createXml );

        // compare the read result with that of the source
        unmarshallAndCompare( createXml, readResultXml );

        // hdr clean up
        deleteAllergyAssessment( createXml );
    }


    /**
     * Tests CRUD of IntoleranceCondition
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testIntoleranceConditionCreateReadXmlCompareDelete( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createIntoleranceConditionXml( requestId );

        // persist
        createIntoleranceCondition( createXml, requestId );

        // read
        String readResultXml = readIntoleranceCondition( createXml );

        // compare the read result with that of the source
        unmarshallAndCompare( createXml, readResultXml );

        // hdr clean up
        deleteIntoleranceCondition( createXml );
    }


    /**
     * Tests the insert/read of the CLOB datatype IC.commentevent.comment with size as 8k
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testIntoleranceConditionWithCommentEventCreateReadXmlCompareDelete( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createIntoleranceConditionWithCommentEventXml( requestId );

        // persist
        createIntoleranceCondition( createXml, requestId );

        // read
        String readResultXml = readIntoleranceCondition( createXml );

        // compare the read result with that of the source
        unmarshallAndCompare( createXml, readResultXml );

        // hdr clean up
        deleteIntoleranceCondition( createXml );
    }


    /**
     * Tests CRUD of VitalObservationEvent
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testVitalObservationEventCreateReadXmlCompareDelete( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createVitalObservationEventXml( requestId );

        // persist
        createVitalObservationEvent( createXml, requestId );

        // read
        String readResultXml = readVitalObservationEvent( createXml );

        // compare the read result with that of the source
        unmarshallAndCompare( createXml, readResultXml );

        // hdr clean up
        deleteVitalObservationEvent( createXml, requestId );
    }


    /**
     * Tests CRUD of OutpatientMedicationPromise to test that ExpandedPatientInstructions and CurrentProviderComments
     * can store more than 4k data.
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testOutpatientMedicationPromiseWithCommentsCreateReadXmlCompareDelete( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createOutpatientMedicationPromiseWithCommentsXml( requestId );

        // persist
        createOutpatientMedicationPromise( createXml, requestId );

        // read
        String readResultXml = readOutpatientMedicationPromise( createXml );

        // compare the read result with that of the source
        unmarshallAndCompare( createXml, readResultXml );

        // hdr clean up
        deleteOutpatientMedicationPromise( createXml );
    }


    /**
     * Tests the hibernate query - OutpatientMedicationPromise.patient.date of gov.va.med.cds.persistence.hibernate.pharmacy.OutpatientMedicationPromise.hbm.xml
     * Tests CRUD of OutpatientMedicationPromise to test that data is brought back since expiry date is within filter date range; it has no cancel date
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testRxWithExpiryDateNWithoutCancelDate( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException,
            DatatypeConfigurationException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createOutpatientMedicationPromiseWithExpiryCancelDatesXml( requestId, 0, 1 );

        // persist
        createOutpatientMedicationPromise( createXml, requestId );

        // read
        String readResultXml = readOutpatientMedicationPromise( createXml, new java.util.Date(), 3 );

        // compare the read result with that of the source
        unmarshallAndCompare( createXml, readResultXml );

        // hdr clean up
        deleteOutpatientMedicationPromise( createXml );
    }


    /**
     * Tests the hibernate query - OutpatientMedicationPromise.patient.date of gov.va.med.cds.persistence.hibernate.pharmacy.OutpatientMedicationPromise.hbm.xml
     * Tests CRUD of OutpatientMedicationPromise to test that data is brought back since expiry date and cancel date are within filter date range.
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testRxWithCancelDateBeforeExpiryDate( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException,
            DatatypeConfigurationException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createOutpatientMedicationPromiseWithExpiryCancelDatesXml( requestId, 1, 2 );

        // persist
        createOutpatientMedicationPromise( createXml, requestId );

        // read
        String readResultXml = readOutpatientMedicationPromise( createXml, new java.util.Date(), 3 );

        // compare the read result with that of the source
        unmarshallAndCompare( createXml, readResultXml );

        // hdr clean up
        deleteOutpatientMedicationPromise( createXml );
    }


    /**
     * Tests the hibernate query - OutpatientMedicationPromise.patient.date of gov.va.med.cds.persistence.hibernate.pharmacy.OutpatientMedicationPromise.hbm.xml
     * Tests CRUD of OutpatientMedicationPromise to test that data is brought back since expiry date and cancel date are within filter date range.
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testRxWithCancelDateAfterExpiryDate( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException,
            DatatypeConfigurationException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createOutpatientMedicationPromiseWithExpiryCancelDatesXml( requestId, 2, 1 );

        // persist
        createOutpatientMedicationPromise( createXml, requestId );

        // read 
        String readResultXml = readOutpatientMedicationPromise( createXml, new java.util.Date(), 3 );

        // compare the read result with that of the source
        unmarshallAndCompare( createXml, readResultXml );

        // hdr clean up
        deleteOutpatientMedicationPromise( createXml );
    }


    /**
     * Tests the hibernate query - OutpatientMedicationPromise.patient.date of gov.va.med.cds.persistence.hibernate.pharmacy.OutpatientMedicationPromise.hbm.xml
     * Tests CRUD of OutpatientMedicationPromise to test that data is brought back since expiry date is in filter date range though cancel date is not.
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testRxWithCancelDateAfterFilterDateRangeNExpiryDateInFilterDateRange( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException,
            DatatypeConfigurationException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createOutpatientMedicationPromiseWithExpiryCancelDatesXml( requestId, 4, 1 );

        // persist
        createOutpatientMedicationPromise( createXml, requestId );

        // read
        String readResultXml = readOutpatientMedicationPromise( createXml, new java.util.Date(), 3 );

        // compare the read result with that of the source
        unmarshallAndCompare( createXml, readResultXml );

        // hdr clean up
        deleteOutpatientMedicationPromise( createXml );
    }


    /**
     * Tests the hibernate query - OutpatientMedicationPromise.patient.date of gov.va.med.cds.persistence.hibernate.pharmacy.OutpatientMedicationPromise.hbm.xml
     * Tests CRUD of OutpatientMedicationPromise to test that data is brought back since cancel date is in filter date range though expiry date is not.
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testRxWithExpiryDateAfterFilterDateRangeNCancelDateInFilterDateRange( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException,
            DatatypeConfigurationException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createOutpatientMedicationPromiseWithExpiryCancelDatesXml( requestId, 1, 4 );

        // persist
        createOutpatientMedicationPromise( createXml, requestId );

        // read
        String readResultXml = readOutpatientMedicationPromise( createXml, new java.util.Date(), 3 );

        // compare the read result with that of the source
        unmarshallAndCompare( createXml, readResultXml );

        // hdr clean up
        deleteOutpatientMedicationPromise( createXml );
    }


    /**
     * Tests the hibernate query - OutpatientMedicationPromise.patient.date of gov.va.med.cds.persistence.hibernate.pharmacy.OutpatientMedicationPromise.hbm.xml
     * Tests CRUD of OutpatientMedicationPromise to test that no data comes back when expirydate is before filter date range and there is no cancel date.
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testRxWithExpiryBeforeFilterDateRange( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException,
            DatatypeConfigurationException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createOutpatientMedicationPromiseWithExpiryCancelDatesXml( requestId, 0, -1 );

        // persist
        createOutpatientMedicationPromise( createXml, requestId );

        // read
        String readResultXml = readOutpatientMedicationPromise( createXml, new java.util.Date(), 1 );

        //read result must have no Rx records
        assertFalse( readResultXml.contains( "<outpatientMedicationPromises>" ) );

        // hdr clean up
        deleteOutpatientMedicationPromise( createXml );
    }


    /**
     * Tests the hibernate query - OutpatientMedicationPromise.patient.date of gov.va.med.cds.persistence.hibernate.pharmacy.OutpatientMedicationPromise.hbm.xml
     * Tests CRUD of OutpatientMedicationPromise to test that no data comes back with expiry date is after filter date range and with no cancel date
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testRxWithExpiryDateAfterFilterDateRange( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException,
            DatatypeConfigurationException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createOutpatientMedicationPromiseWithExpiryCancelDatesXml( requestId, 0, 2 );

        // persist
        createOutpatientMedicationPromise( createXml, requestId );

        // read
        String readResultXml = readOutpatientMedicationPromise( createXml, new java.util.Date(), 1 );

        //      read result must have no Rx records
        assertFalse( readResultXml.contains( "<outpatientMedicationPromises>" ) );
        // hdr clean up
        deleteOutpatientMedicationPromise( createXml );
    }


    /**
     * Tests the hibernate query - OutpatientMedicationPromise.patient.date of gov.va.med.cds.persistence.hibernate.pharmacy.OutpatientMedicationPromise.hbm.xml
     * Tests CRUD of OutpatientMedicationPromise to test that no data comes back with cancel date before expiry date and filter date range
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testRxWithCancelDateBeforeExpiryNBeforeFilterDateRange( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException,
            DatatypeConfigurationException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createOutpatientMedicationPromiseWithExpiryCancelDatesXml( requestId, -1, 1 );

        // persist
        createOutpatientMedicationPromise( createXml, requestId );

        // read
        String readResultXml = readOutpatientMedicationPromise( createXml, new java.util.Date(), 2 );

        //      read result must have no Rx records
        assertFalse( readResultXml.contains( "<outpatientMedicationPromises>" ) );

        // hdr clean up
        deleteOutpatientMedicationPromise( createXml );
    }


    /**
     * Tests the hibernate query - OutpatientMedicationPromise.patient.date of gov.va.med.cds.persistence.hibernate.pharmacy.OutpatientMedicationPromise.hbm.xml
     * Tests CRUD of OutpatientMedicationPromise to test that no data comes back with cancel date before expiry date and cancel date is after filter date range
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testRxWithCancelDateBeforeExpiryNAfterFilterDateRange( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException,
            DatatypeConfigurationException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createOutpatientMedicationPromiseWithExpiryCancelDatesXml( requestId, 2, 3 );

        // persist
        createOutpatientMedicationPromise( createXml, requestId );

        // read
        String readResultXml = readOutpatientMedicationPromise( createXml, new java.util.Date(), 1 );

        //      read result must have no Rx records
        assertFalse( readResultXml.contains( "<outpatientMedicationPromises>" ) );

        // hdr clean up
        deleteOutpatientMedicationPromise( createXml );
    }


    /**
     * Tests the hibernate query - OutpatientMedicationPromise.patient.date of gov.va.med.cds.persistence.hibernate.pharmacy.OutpatientMedicationPromise.hbm.xml
     * Tests CRUD of OutpatientMedicationPromise to test that no data comes back with cancel date after expiry date and cancel date is before filter date range
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testRxWithCancelDateAfterExpiryNBeforeFilterDateRange( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException,
            DatatypeConfigurationException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createOutpatientMedicationPromiseWithExpiryCancelDatesXml( requestId, -1, -2 );

        // persist
        createOutpatientMedicationPromise( createXml, requestId );

        // read
        String readResultXml = readOutpatientMedicationPromise( createXml, new java.util.Date(), 1 );

        //      read result must have no Rx records
        assertFalse( readResultXml.contains( "<outpatientMedicationPromises>" ) );

        // hdr clean up
        deleteOutpatientMedicationPromise( createXml );
    }


    /**
     * Tests the hibernate query - OutpatientMedicationPromise.patient.date of gov.va.med.cds.persistence.hibernate.pharmacy.OutpatientMedicationPromise.hbm.xml
     * Tests CRUD of OutpatientMedicationPromise to test that no data comes back with cancel date after expiry date and cancel date is after filter date range
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testRxWithCancelDateAfterExpiryNAfterFilterDateRange( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException,
            DatatypeConfigurationException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createOutpatientMedicationPromiseWithExpiryCancelDatesXml( requestId, 3, 2 );

        // persist
        createOutpatientMedicationPromise( createXml, requestId );

        // read
        String readResultXml = readOutpatientMedicationPromise( createXml, new java.util.Date(), 1 );

        //      read result must have no Rx records
        assertFalse( readResultXml.contains( "<outpatientMedicationPromises>" ) );

        // hdr clean up
        deleteOutpatientMedicationPromise( createXml );
    }


    /**
     * Tests CRUD of OutpatientMedicationPromise; This is a specific test to show that more than 2 of refill/partial
     * type dispenses can be created for a pharmacy record.
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testOutpatientMedicationPromiseWithDispensesCreateReadXmlCompareDelete( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createOutpatientMedicationPromiseWithSpecificDispensesXml( requestId );

        // persist
        createOutpatientMedicationPromise( createXml, requestId );

        // read
        String readResultXml = readOutpatientMedicationPromise( createXml );

        // compare the read result with that of the source
        unmarshallAndCompare( createXml, readResultXml );

        // hdr clean up
        deleteOutpatientMedicationPromise( createXml );
    }


    /**
     * Tests CRUD of Lab
     * 
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    @Test
    @Suite( groups = { "brokentest" } )
    public void testLabPromiseCreateReadXmlCompareDelete( )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException
    {
        // create an VHIM XML record
        String requestId = new UniqueIdentifier().toString();
        String createXml = createLabXml( requestId );

        // persist
        createLab( createXml, requestId );

        // read
        String readResultXml = readLabPromise( createXml );

        // compare the read result with that of the source
        unmarshallAndCompare( createXml, readResultXml );

        // hdr clean up
        deleteLabPromise( createXml );
    }


    /**
     * Create filter request xml for AllergyAssessment
     * 
     * @param xml
     * @return xpath filter string
     */
    protected abstract String createXpathFilterFromAllergyAssessment( String xml );


    /**
     * Create filter request xml for IntoleranceCondition
     * 
     * @param xml
     * @return xpath filter string
     */
    protected abstract String createXpathFilterFromIntoleranceCondition( String xml );


    /**
     * Create filter request xml for VitalObservationEvent
     * 
     * @param xml
     * @return xpath filter string
     */
    protected abstract String createXpathFilterFromVitalObservationEvent( String xml );


    /**
     * Create filter request xml for OutpatientMedicationPromise
     * 
     * @param xml
     * @return xpath filter string
     */
    protected abstract String createXpathFilterFromOutpatientMedicationPromise( String xml, Date startDate, int ednDate )
        throws DatatypeConfigurationException;


    /**
     * Create filter request xml for OutpatientMedicationPromise
     * 
     * @param xml
     * @return xpath filter string
     */
    protected abstract String createXpathFilterFromOutpatientMedicationPromise( String xml );


    /**
     * Create filter request xml for Lab
     * 
     * @param xml
     * @return xpath filter string
     */
    protected abstract String createXpathFilterFromLab( String xml );


    /**
     * Create filter request xml for IntoleranceConditionDateFilter
     * 
     * @param xml
     * @return xpath filter string
     */

    protected abstract String createXpathFilterFromIntoleranceConditionDateFilter( String xml, String startDate, String endDate );


    /**
     * Returns the VDMBuilder result for create allergy assessment
     * 
     * @param aRequestId request id
     * @return xml string
     */
    protected abstract String createAllergyAssessmentXml( String aRequestId );


    /**
     * Returns the VDMBuilder result for create IC
     * 
     * @param aRequestId request id
     * @return xml string
     */
    protected abstract String createIntoleranceConditionXml( String aRequestId );


    /**
     * Returns the VDMBuilder result for create IC
     * 
     * @param aRequestId request id
     * @return xml string
     */
    protected abstract String createIntoleranceConditionWithCommentEventXml( String aRequestId )
        throws IOException;


    /**
     * Returns the VDMBuilder result for create VITALS
     * 
     * @param aRequestId request id
     * @return xml string
     */
    protected abstract String createVitalObservationEventXml( String aRequestId );


    /**
     * Returns the VDMBuilder result for create o/p Rx
     * 
     * @param aRequestId request id
     * @return xml string
     */
    protected abstract String createOutpatientMedicationPromiseXml( String aRequestId );


    /**
     * Returns the VDMBuilder result for create o/p Rx
     * 
     * @param aRequestId request id
     * @return xml string
     */
    protected abstract String createOutpatientMedicationPromiseWithCommentsXml( String aRequestId )
        throws IOException;


    /**
     * Returns the VDMBuilder result for create o/p Rx
     * 
     * @param aRequestId request id
     * @return xml string
     */
    protected abstract String createOutpatientMedicationPromiseWithExpiryCancelDatesXml( String aRequestId, int cancelDate, int expirationDate );


    /**
     * Returns the VDMBuilder result for create o/p Rx
     * 
     * @param aRequestId request id
     * @return xml string
     */
    protected abstract String createOutpatientMedicationPromiseWithSpecificDispensesXml( String aRequestId );


    /**
     * Returns the VDMBuilder result for create Lab
     * 
     * @param aRequestId request id
     * @return xml string
     */
    protected abstract String createLabXml( String aRequestId );


    /**
     * Returns the VDMBuilder result for create IC with obervationdate
     * 
     * @param observationTime The observation time.
     * @return The XML intolerance condition.
     */
    protected abstract String createIntoleranceConditionWithDateRangeXml( String observationTime );


    // protected abstract String createIntoleranceConditionWithDateRangeXml( String observationTime, String aRequestId
    // );
    /**
     * The following methods get filter ids for the given clinical domains.
     * 
     * 
     * @return filter id
     */
    protected abstract String getAllergyAssessmentFilterId( );


    protected abstract String getIntoleranceConditionFilterId( );


    protected abstract String getVitalObservationEventFilterId( );


    protected abstract String getOutpatientMedicationPromiseFilterId( );


    protected abstract String getLabFilterId( );


    /**
     * The following return the read tempalte ids for the clinical domains
     * 
     * @return
     */
    // protected abstract String getAllergyAssessmentReadTemplateId( );
    // protected abstract String getIntoleranceConditionReadTemplateId( );
    // protected abstract String getVitalObservationEventReadTemplateId( );
    // protected abstract String getOutpatientMedicationPromiseReadTemplateId( );
    /**
     * The following return the create tempalte ids for the clinical domains
     * 
     * @return
     */
    // protected abstract String getAllergyAssessmentCreateTemplateId( );
    // protected abstract String getIntoleranceConditionCreateTemplateId( );
    // protected abstract String getVitalObservationEventCreateTemplateId( );
    // protected abstract String getOutpatientMedicationPromiseCreateTemplateId( );
    /**
     * The following return the delete tempalte ids for the clinical domains
     * 
     * @return
     */
    // protected abstract String getAllergyAssessmentDeleteTemplateId( );
    // protected abstract String getIntoleranceConditionDeleteTemplateId( );
    // protected abstract String getVitalObservationEventDeleteTemplateId( );
    // protected abstract String getOutpatientMedicationPromiseDeleteTemplateId( );
    /**
     * modifies the template metadata of given xml for reusing the same xml for CRUD operations for given clinical
     * domain name
     * 
     * @param templateId
     * @param resultXml
     * @param domainName
     * @return modified template meta data
     */
    protected abstract String modifyTemplateMetaDataOfCRUADResultXml( String templateId, String resultXml, String domainName );


    /**
     * Checks for no erros in the xml
     * 
     * @param createResult
     */
    protected abstract void checkForNoErrorsInXml( String createResult );


    /**
     * Compares and checks the read result xml aganist the filer's data range.
     * 
     * @param readResult
     * @param startDate
     * @param endDate
     */
    protected abstract void compareAllergyFilterAndResults( String readResult, String startDate, String endDate, boolean positiveTest );


    /**
     * Compares and checks the read result xml aganist the invalid date.
     * 
     * @param readResult
     * @param invalidDate
     */
    protected abstract void ensureAllergyContainsInvalidDate( String readResult, String invalidDate );


    /**
     * Unmarshalls a xml and does xml compare.
     * 
     * @param controlXml
     * @param sourceXml
     * @throws SAXException
     * @throws IOException
     * @throws ParserConfigurationException
     * @throws XmlCompareException
     */
    protected abstract void unmarshallAndCompare( String controlXml, String sourceXml )
        throws SAXException,
            IOException,
            ParserConfigurationException,
            XmlCompareException;


    /**
     * The following methods do CRUD FOR ALLERGY ASSESSMENT.
     * 
     * @param createRequestXml
     */
    private void createAllergyAssessment( String createRequestXml, String aRequestId )
    {
        String createTemplateId = TemplateIdHelper.ALLERGY_ASSESSMENT_CREATE_TEMPLATE_ID;
        Document result = getRequestProcessor().createClinicalData( createRequestXml, createTemplateId, new UniqueIdentifier().toString() );
        checkForNoErrorsInXml( result.asXML() );
    }


    private String readAllergyAssessment( String xml )
    {

        String readTemplateId = TemplateIdHelper.ALLERGY_ASSESSMENT_READ_TEMPLATE_ID;
        String filterXml = createXpathFilterFromAllergyAssessment( xml );
        String filterId = getAllergyAssessmentFilterId();
        Document result = getRequestProcessor().readClinicalData( readTemplateId, filterXml, filterId, new UniqueIdentifier().toString() );
        checkForNoErrorsInXml( result.asXML());
        return result.asXML();
    }


    private void deleteAllergyAssessment( String xml )
    {
        String deleteTemplateId = TemplateIdHelper.ALLERGY_ASSESSMENT_DELETE_TEMPLATE_ID;
        String deleteXmlRequest = modifyTemplateMetaDataOfCRUADResultXml( deleteTemplateId, xml, ALLERGY_ASSESSEMENT );
        Document result = getRequestProcessor().deleteClinicalData( deleteXmlRequest, deleteTemplateId, new UniqueIdentifier().toString() );
        checkForNoErrorsInXml( result.asXML() );
    }


    /**
     * The following methods do CRUD for IC
     * 
     * @param createRequestXml
     */
    private void createIntoleranceCondition( String createRequestXml, String aRequestId )
    {
        String createTemplateId = TemplateIdHelper.INTOLERANCE_CONDITION_CREATE_TEMPLATE_ID;
        Document result = getRequestProcessor().createClinicalData( createRequestXml, createTemplateId, new UniqueIdentifier().toString() );
        checkForNoErrorsInXml(result.asXML() );
    }


    private String readIntoleranceCondition( String xml )
    {

        String readTemplateId = TemplateIdHelper.INTOLERANCE_CONDITION_READ_TEMPLATE_ID;
        String filterXml = createXpathFilterFromIntoleranceCondition( xml );
        String filterId = getIntoleranceConditionFilterId();
        Document result = getRequestProcessor().readClinicalData( readTemplateId, filterXml, filterId, new UniqueIdentifier().toString() );
        checkForNoErrorsInXml( result.asXML() );
        return result.asXML();
    }


    private void deleteIntoleranceCondition( String xml )
    {
        String deleteTemplateId = TemplateIdHelper.INTOLERANCE_CONDITION_DELETE_TEMPLATE_ID;
        String deleteXmlRequest = modifyTemplateMetaDataOfCRUADResultXml( deleteTemplateId, xml, INTOLERANCE_CONDITION );
        Document result = getRequestProcessor().deleteClinicalData( deleteXmlRequest, deleteTemplateId, new UniqueIdentifier().toString() );
        checkForNoErrorsInXml( result.asXML());
    }


    /**
     * The following methods do CRUD for Vitals
     * 
     * @param createRequestXml
     */
    private void createVitalObservationEvent( String createRequestXml, String aRequestId )
    {
        String createTemplateId = TemplateIdHelper.VITALSIGNS_CREATE_TEMPLATE_ID;
        Document result = getRequestProcessor().createClinicalData( createRequestXml, createTemplateId, aRequestId );
        checkForNoErrorsInXml( result.asXML() );
    }


    private String readVitalObservationEvent( String xml )
    {
        String readTemplateId = TemplateIdHelper.VITALSIGNS_READ_TEMPLATE_ID;
        String filterXml = createXpathFilterFromVitalObservationEvent( xml );
        String filterId = getVitalObservationEventFilterId();
        Document result = getRequestProcessor().readClinicalData( readTemplateId, filterXml, filterId, new UniqueIdentifier().toString() );
        checkForNoErrorsInXml( result.asXML() );
        return result.asXML();
    }


    private void deleteVitalObservationEvent( String xml, String aRequestId )
    {
        String deleteTemplateId = TemplateIdHelper.VITALSIGNS_DELETE_TEMPLATE_ID;
        String deleteXmlRequest = modifyTemplateMetaDataOfCRUADResultXml( deleteTemplateId, xml, VITAL_OBSERVATION_EVENT );
        Document result = getRequestProcessor().deleteClinicalData( deleteXmlRequest, deleteTemplateId, new UniqueIdentifier().toString() );
        checkForNoErrorsInXml( result.asXML() );
    }


    /**
     * The following methods do CRUD for O/P Rx.
     * 
     * @param createRequestXml
     */
    private void createOutpatientMedicationPromise( String createRequestXml, String aRequestId )
    {
        String createTemplateId = TemplateIdHelper.PHARMACY_CREATE_TEMPLATE_ID;
        Document result = getRequestProcessor().createClinicalData( createRequestXml, createTemplateId, new UniqueIdentifier().toString() );
        checkForNoErrorsInXml( result.asXML() );
    }


    /**
     * The following methods do CRUD for Lab.
     * 
     * @param createRequestXml
     */
    private void createLab( String createRequestXml, String aRequestId )
    {
        String createTemplateId = TemplateIdHelper.LAB_CREATE_TEMPLATE_ID;
        Document result = getRequestProcessor().createClinicalData( createRequestXml, createTemplateId, new UniqueIdentifier().toString() );
        checkForNoErrorsInXml( result.asXML() );
    }


    private String readOutpatientMedicationPromise( String xml )
    {

        String readTemplateId = TemplateIdHelper.PHARMACY_READ_TEMPLATE_ID;
        String filterXml = createXpathFilterFromOutpatientMedicationPromise( xml );
        String filterId = getOutpatientMedicationPromiseFilterId();
        Document result = getRequestProcessor().readClinicalData( readTemplateId, filterXml, filterId, new UniqueIdentifier().toString() );
        checkForNoErrorsInXml( result.asXML() );
        return result.asXML();
    }


    private String readOutpatientMedicationPromise( String xml, java.util.Date aStartDate, int aEndDate )
        throws DatatypeConfigurationException
    {

        String readTemplateId = TemplateIdHelper.PHARMACY_READ_TEMPLATE_ID;
        String filterXml = createXpathFilterFromOutpatientMedicationPromise( xml, aStartDate, aEndDate );
        String filterId = getOutpatientMedicationPromiseFilterId();
        Document result = getRequestProcessor().readClinicalData( readTemplateId, filterXml, filterId, new UniqueIdentifier().toString() );
        checkForNoErrorsInXml( result.asXML() );
        return result.asXML();
    }


    private String readLabPromise( String xml )
    {
        String readTemplateId = TemplateIdHelper.LAB_READ_TEMPLATE_ID;
        String filterXml = createXpathFilterFromLab( xml );
        String filterId = getLabFilterId();
        Document result = getRequestProcessor().readClinicalData( readTemplateId, filterXml, filterId, new UniqueIdentifier().toString() );
        checkForNoErrorsInXml( result.asXML() );
        return result.asXML();
    }


    private void deleteOutpatientMedicationPromise( String xml )
    {
        String deleteTemplateId = TemplateIdHelper.PHARMACY_DELETE_TEMPLATE_ID;
        String deleteXmlRequest = modifyTemplateMetaDataOfCRUADResultXml( deleteTemplateId, xml, OUTPATIENT_MEDICATION_PROMISE );
        Document result = getRequestProcessor().deleteClinicalData( deleteXmlRequest, deleteTemplateId, new UniqueIdentifier().toString() );
        checkForNoErrorsInXml( result.asXML());
    }


    private void deleteLabPromise( String xml )
    {
        String deleteTemplateId = TemplateIdHelper.LAB_DELETE_TEMPLATE_ID;
        String deleteXmlRequest = modifyTemplateMetaDataOfCRUADResultXml( deleteTemplateId, xml, LAB_PROMISE );
        Document result = getRequestProcessor().deleteClinicalData( deleteXmlRequest, deleteTemplateId, new UniqueIdentifier().toString() );
        checkForNoErrorsInXml( result.asXML());
    }
}
