

package gov.va.med.cds.persistence.hibernate;


import static gov.va.med.cds.exception.ErrorCodeEnum.HDRII_OPERATION_FAILED;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.dom4j.Element;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.exception.ConstraintViolationException;

import gov.va.med.cds.clinicaldata.DomainEntryPoint;
import gov.va.med.cds.clinicaldata.Operation;
import gov.va.med.cds.exception.ErrorCodeEnum;
import gov.va.med.cds.exception.OperationNotSupportedException;
//import gov.va.med.cds.persistence.CensusSurveyConstant;
import gov.va.med.cds.persistence.PersistenceException;
//import gov.va.med.cds.persistence.ReadException;
import gov.va.med.cds.persistence.WritePersistenceManagerInterface;
import gov.va.med.cds.rules.BooleanRuleInterface;
import gov.va.med.cds.template.generated.clinicaldata.Patients;
import gov.va.med.cds.template.generated.clinicaldata.RoutingDataType;
import gov.va.med.cds.template.generated.common.ClinicalDataPatient;
//import gov.va.med.cds.template.generated.surveys.CensusMasterSegment;
import gov.va.med.cds.template.generated.surveys.CensusSurveyResponse;
import gov.va.med.cds.template.generated.surveyscommon.Vendor;
import gov.va.med.cds.util.DateTimeUtil;
//import gov.va.med.cds.template.generated.surveys.CensusMasterIngest;


public class WriteableCensusSurveyPersistenceManager
    extends
        AbstractHibernatePersistenceManager
    implements
        WritePersistenceManagerInterface
{

    //private static final String PATIENT = "patient";
    //private static final String surveyPatient = "surveyPatient";
    private List<BooleanRuleInterface> rules;
    private String cdsAppName;


    public boolean isApplicable( Object critera )
        throws PersistenceException
    {
        boolean b = false;
        for ( BooleanRuleInterface r : rules )
        {
            b = r.evaluate( critera );
            if ( b )
            {
                break;
            }
        }

        return b;
    }


    public String performCUADOnClinicalData( String templateId, Operation operation, Object aObject, DomainEntryPoint domainEntryPoint )
        throws PersistenceException
    {
        throw new OperationNotSupportedException( ErrorCodeEnum.METHOD_NOT_IMPLEMENTED );
        //return "";
    }


    /**
    * Handles the CUAD requests and applies the transaction to the data-source as directed by the request type.
    * 
    * @param templateId The identifier of the template being created, updated, appended, or deleted.
    * @param requestType - request type could be Create, Update, Append and Delete.
    * @param object - CDM objects to apply to the data-source.
    */
    //@Override
    @SuppressWarnings( { "rawtypes", "unchecked" } )
    public String performCUADOnPatientsData( String templateId, String aRequestId, Operation aOperation, Object aObject,
                    DomainEntryPoint domainEntryPoint )
        throws PersistenceException
    {
        Session session = null;
        String resultId = "";

        try
        {
            session = getSessionFactory( templateId ).getCurrentSession();

            Patients patients = ( Patients )unmarshalElementToObject( ( Element )aObject, domainEntryPoint );
            List<ClinicalDataPatient> patientsList = patients.getPatient();
            // Long censusMasterID = retrieveOrStoreCensusMasterIngest(session, patients);
            // Long censusSegmentID = retrieveOrStoreMasterSegment(session, patients, censusMasterID);

            //===============================================
            /* Following code is used to called stored procedures in Database Package which updated Census Master and Segment tables and return IDs*/
            Long censusMasterID = 0L;
            Long censusSegmentID = 0L;

            Integer censusExpectedCount = patients.getSegment().getLast();
            String segmentDatetime = patients.getSegment().getDatetime().toString();
            Integer currentSegment = patients.getSegment().getCurrent();

            // RoutingDataType is used to send census acknowledgement at the end of the census transformation process 
            RoutingDataType routingData = patients.getRoutingData().get( 0 );
            String sendingApplication = routingData.getSendingApplication();
            String stationNumber = routingData.getStationNumber();
            String sendingFacility = routingData.getSendingFacility();
            String receivingApplication = routingData.getReceivingApplication();
            String receivingFacility = routingData.getReceivingFacility();

            ClinicalDataPatient patient = patientsList.get( 0 );
            CensusSurveyResponse censusSurveyResponse = patient.getCensusSurveyResponse().get( 0 );
            Vendor vendor = censusSurveyResponse.getVendor();
            String vendorName = vendor.getVendorName();
            String vendorFacility = vendor.getVendorNumber();
            Date reportStartDate = censusSurveyResponse.getReportStartDate();
            Date reportEndDate = censusSurveyResponse.getReportEndDate();

            //check currentSegment is NOT more than expected segments count
            /*if ( currentSegment > censusExpectedCount )
            {
                throw new PersistenceException( ErrorCodeEnum.WRITE_REQUEST_CENSUS_NO_OF_SEGS_RECEPTION_TIME_EXPIRED,
                                DateTimeUtil.convertDate2String( reportStartDate ), DateTimeUtil.convertDate2String( reportEndDate ), aRequestId,
                                stationNumber );
            }*/

            Query query = session.getNamedQuery( "census_master_record_mgt.census_master_records" ).setParameter( "reportStartDate", reportStartDate )
                            .setParameter( "vendorName", vendorName ).setParameter( "vendorFacility", vendorFacility )
                            .setParameter( "segmentDatetime", segmentDatetime ).setParameter( "censusExpectedCount", censusExpectedCount )
                            .setParameter( "currentSegment", currentSegment ).setParameter( "senderAddress", null)
                            .setParameter( "reportEndDt", reportEndDate).setParameter( "requestId", aRequestId)
                            .setParameter( "sendingApplication", sendingApplication).setParameter( "stationNo", stationNumber)
                            .setParameter( "sendingFacility", sendingFacility).setParameter( "receivingApplication", receivingApplication)
                            .setParameter( "receivingFacility", receivingFacility);

            List<CensusIDs> result = query.list();
            CensusIDs censusIDs = result.get( 0 );

            String errorMessage = censusIDs.geterrorMessage();
            String ackStatus = censusIDs.getAckStatus();
            
            if ( !errorMessage.equalsIgnoreCase( "SUCCESS" ) ) {
                errorHanding( errorMessage, segmentDatetime, reportStartDate, currentSegment, reportEndDate, aRequestId, stationNumber, ackStatus );
            }

            censusMasterID = censusIDs.getcensusMasterID();
            censusSegmentID = censusIDs.getcensusSegmentID();

            //=========================================

            if ( LOGGER.isDebugEnabled() )
            {
                LOGGER.debug( gov.va.med.cds.util.LogMessageUtil.buildMessage( templateId, aRequestId, cdsAppName,
                                "Storing Census records for:" + patientsList.size() + " patients" ) );
            }

            int batchCount = 0;
            double start = System.currentTimeMillis();

            CensusSurveyResponse censusRecord = null;
            for ( int i = 1; i <= patientsList.size(); i++ )
            {
                batchCount++ ;
                // ClinicalDataPatient patient = (ClinicalDataPatient)patientsList.get( i-1 );
                patient = ( ClinicalDataPatient )patientsList.get( i - 1 );

                censusRecord = patient.getCensusSurveyResponse().get( 0 );
                censusRecord.setRequestId( aRequestId );
                censusRecord.setCensusSegmentID( censusSegmentID );
                censusRecord.setCensusMasterID( censusMasterID );

                resultId = createData( session, censusRecord );
                if ( batchCount % 100 == 0 ) //100, same as the JDBC batch size
                {
                    if ( LOGGER.isDebugEnabled() )
                    {
                        LOGGER.debug( "Writing batch of 100 census records: " + i );
                    }
                    //flush a batch of inserts and release memory:
                    session.flush();
                    session.clear();
                }
            }

            /*flush a last uneven batch of inserts and release memory which does not fall under mod 100 */
            session.flush();
            session.clear();

            Query completeQuery = session.getNamedQuery( "census_master_record_mgt.census_segment_complete" )
                            .setParameter( "censusMasterID", censusMasterID ).setParameter( "censusSegmentID", censusSegmentID );
            List resultSegment = completeQuery.list();

            double end = ( System.currentTimeMillis() - start );
            if ( LOGGER.isDebugEnabled() )
            {
                LOGGER.debug( "===========================================================================\n" );
                LOGGER.debug( "Total time storing census records: " + end + "\n" );
                LOGGER.debug( "Total item or record count: " + batchCount + "\n" );
                LOGGER.debug( "===========================================================================\n" );
            }
        }
        // try to figure out what caused the violation
        catch ( ConstraintViolationException e )
        {
            throw new HibernateConstraintViolationException( e );
        }
        // already handled and turned into one of ours so rethrow it
        catch ( PersistenceException e )
        {
            throw e;
        }
        // any other problems are just big and will require someone to look at
        // so check log file
        catch ( Exception e )
        {
            String rootCauseMessage = ExceptionUtils.getRootCause( e ) == null ? e.getMessage() : ExceptionUtils.getRootCause( e ).getMessage();
            throw new PersistenceException( HDRII_OPERATION_FAILED, e, aOperation.name(), rootCauseMessage, domainEntryPoint.getName() );
        }

        return resultId;
    }


    protected void errorHanding( String errorMessage, String segmentDatetime, Date reportStartDate, int currentSegment, Date reportEndDate, String requestId, String vendorId, String ackStatus )
        throws PersistenceException
    {
        //census segment han an error, and ack_status is NOT INPROGRESS, ignore the rest below
        if ( null != ackStatus && !ackStatus.equalsIgnoreCase( "INPROGRESS" ) )
        {
            throw new PersistenceException( ErrorCodeEnum.WRITE_REQUEST_CENSUS_ACK_ALREADY_SENT );
        }
        
        if ( errorMessage.contentEquals( "WRITE_REQUEST_CENSUS_TOO_MANY_SEGMENTS" ))
        {
            throw new PersistenceException( ErrorCodeEnum.WRITE_REQUEST_CENSUS_NO_OF_SEGS_RECEPTION_TIME_EXPIRED,
                            DateTimeUtil.convertDate2String( reportStartDate ), DateTimeUtil.convertDate2String( reportEndDate ), requestId, vendorId );
        } else if ( errorMessage.contentEquals( "WRITE_REQUEST_CENSUS_SEGMENT_DUPLICATE" )
                        || errorMessage.contentEquals( "WRITE_REQUEST_CENSUS_ALREADY_SUBMITTED" ) )
        {
            throw new PersistenceException( ErrorCodeEnum.WRITE_REQUEST_CENSUS_SEGMENT_DUPLICATE, DateTimeUtil.convertDate2String( reportStartDate ),
                            segmentDatetime, String.valueOf( currentSegment ) );
        }
        else if ( errorMessage.contentEquals( "WRITE_REQUEST_CENSUS_STATUS_ALREADY_COMPLETE" ) )
        {
            throw new PersistenceException( ErrorCodeEnum.WRITE_REQUEST_CENSUS_STATUS_COMPLETE, DateTimeUtil.convertDate2String( reportStartDate ),
                            segmentDatetime );
        }
        else if ( errorMessage.contentEquals( "WRITE_REQUEST_CENSUS_INVALID_START_DATE" ) )
        {
            throw new PersistenceException( ErrorCodeEnum.WRITE_REQUEST_CENSUS_INVALID_START_DATE, DateTimeUtil.convertDate2String( reportStartDate ),
                            DateTimeUtil.convertDate2String( reportEndDate ), requestId, vendorId );
        }
        else
        {
            throw new PersistenceException( ErrorCodeEnum.WRITE_REQUEST_CENSUS_SEGMENT_FAILED, DateTimeUtil.convertDate2String( reportStartDate ),
                            segmentDatetime, String.valueOf( currentSegment ) );
        }
    }

    /*
    @SuppressWarnings("unchecked")
    @Override
    public List<CensusMasterIngest> performReadOnCensusMetaData(CensusMasterIngest incomingCensusElement) throws CensusException {
    	
    	Session aSession = getSessionFactory(incomingCensusElement.getTemplateId()).getCurrentSession();
    	Criteria aCriteria = aSession.createCriteria("censusMasterIngest");
    	aCriteria.add(Example.create(incomingCensusElement));
    
    	return aCriteria.list();
    	
    }
    @Override
    public String performCUADOnCensusMetaData(Operation aOperation, CensusMasterIngest censusMasterIngest) throws PersistenceException {
    	Session session = getSessionFactory(censusMasterIngest.getTemplateId()).getCurrentSession();
    	Long censusMasterId = performCUADOnCensusMasterIngest(session, censusMasterIngest);
    	censusMasterIngest.setCensusMasterId(censusMasterId);
    	Long censusSegmentId = performCUADOnCensusMasterSegment(session, censusMasterIngest);
    	censusMasterIngest.setCensusSegmentId(censusSegmentId);
    	return censusMasterIngest.getCurrentSegmentNo()+"";
    } */


    /**
     * Handles hibernate HDRII create processing.
     * 
     * @param session - active hibernate session.
     * @param aObject - create request.
     */
    //@Override
    protected String createData( Session session, CensusSurveyResponse surveyResponse )
    {

        /* Following is for the multi-table relational solution 
        
        validateAndRetrieveCensusVendor( session, surveyResponse );
        checkVendorTotalTime += (System.currentTimeMillis()-start);
        
        start= System.currentTimeMillis();
        validateAndRetrieveFacility( session, surveyResponse );
        vendorFacilityTotalTime += (System.currentTimeMillis() -start);
        
        start= System.currentTimeMillis();
        retrieveOrStoreData(session, surveyResponse, "survey");
                                saveSurveyTotalTime += (System.currentTimeMillis()-start);
                                
                                start= System.currentTimeMillis();
                                retrieveOrStoreData(session, surveyResponse, "surveyPatient");
                                savePatientTotalTime += (System.currentTimeMillis()-start);
                                
                                start= System.currentTimeMillis();
                                validateAndRetrieveCCFacility( session, surveyResponse );
                                ccFacilityTotalTime += (System.currentTimeMillis()-start);
                                
                                start= System.currentTimeMillis();
                                retrieveOrStoreData(session, surveyResponse, "careCoordinator");
                                saveCCTotalTime+= (System.currentTimeMillis()-start);
                                
                                start= System.currentTimeMillis();
                                storeModalities( session, surveyResponse );
                                saveModalityTotalTime += (System.currentTimeMillis()-start);
                                */

        return session.save( surveyResponse ).toString();
    }

    /*
        protected Long retrieveOrStoreMasterSegment(Session session, Patients response, Long censusMasterId) {
        		
        	    CensusMasterIngest censusMasterIngest = new CensusMasterIngest(); 
                censusMasterIngest.setCensusMasterId(censusMasterId);
                Integer currentSegment = response.getSegment().getCurrent();
                censusMasterIngest.setCurrentSegmentNo(currentSegment);
                censusMasterIngest.setCurrentSegmentProcessStatus(CensusSurveyConstant.INGEST_COMPLETE);
                return performCUADOnCensusMasterSegment(session, censusMasterIngest);
                
        }*/

    /*
    @SuppressWarnings("unchecked")
    private Long performCUADOnCensusMasterSegment(Session session, CensusMasterIngest censusMasterIngest){
    	
    	Long censusSegmentId = null;	
    	List<CensusMasterSegment> results = null;
    	CensusMasterSegment incomingSegment = new CensusMasterSegment();
    	          
        incomingSegment.setCurrentSegment(censusMasterIngest.getCurrentSegmentNo());
        incomingSegment.setCensusMasterID(censusMasterIngest.getCensusMasterId());
        incomingSegment.setProcessStatus(censusMasterIngest.getCurrentSegmentProcessStatus());
            
        Criteria criteria = session.createCriteria("censusMasterSegment");
        criteria.add(Example.create(incomingSegment));
        try {
          	results = criteria.list();
        } 
        catch (org.hibernate.exception.GenericJDBCException e) {
            throw new ReadException(ErrorCodeEnum.HIBERNATE_READ_FAILURE, e, e.getMessage());
        }
            
        if (results.size() < 1) {
    
                 censusSegmentId = (Long)session.save("censusMasterSegment", incomingSegment);
        } else {
               //duplicate segment
               throw new ReadException(ErrorCodeEnum.HIBERNATE_CREATE_FAILURE, censusMasterIngest.getCurrentSegmentNo()+"");
        }
        return censusSegmentId;
    }*/
    /**
     * 
     * @param session
     * @param response
     * @return created or updated record id
     */
    /*
    protected Long retrieveOrStoreCensusMasterIngest(Session session, Patients response) {
    		
    		CensusMasterIngest censusMasterIngest = new CensusMasterIngest();
            Integer lastSegment = response.getSegment().getLast();
            censusMasterIngest.setCensusExpectedCount(lastSegment);
            
            String segmentDatetime = response.getSegment().getDatetime().toString();
            censusMasterIngest.setSegmentDatetime(segmentDatetime);
           
            List<ClinicalDataPatient> patientsList = response.getPatient();
            ClinicalDataPatient patient= patientsList.get(0);
            CensusSurveyResponse censusSurveyResponse = patient.getCensusSurveyResponse().get(0);
            Vendor vendor = censusSurveyResponse.getVendor();
            String vendorName = vendor.getVendorName();                 
            censusMasterIngest.setVendorName(vendorName);
            
            String vendorFacility = vendor.getVendorNumber();
            censusMasterIngest.setVendorFacility(vendorFacility);
            
            Date reportStartDate = censusSurveyResponse.getReportStartDate();	
            censusMasterIngest.setReportStartDatetime(reportStartDate);
            
            return performCUADOnCensusMasterIngest(session, censusMasterIngest);
            
    }*/
    /**
     * 
     * @param session
     * @param censusMasterIngest
     * @return newly inserted record ID
     */
    /*
    @SuppressWarnings("unchecked")
    private Long performCUADOnCensusMasterIngest(Session session, CensusMasterIngest censusMasterIngest){
    	
    	 	List<CensusMasterIngest> results = null;
            String status = CensusSurveyConstant.INGEST_PENDING;
            Long censusMasterID = null;
            CensusMasterIngest incomingCensus = new CensusMasterIngest();
           
            incomingCensus.setCensusExpectedCount(censusMasterIngest.getCensusExpectedCount());
            incomingCensus.setSegmentDatetime(censusMasterIngest.getSegmentDatetime());
            incomingCensus.setVendorName(censusMasterIngest.getVendorName());
            incomingCensus.setVendorFacility(censusMasterIngest.getVendorFacility());
            incomingCensus.setReportStartDatetime(censusMasterIngest.getReportStartDatetime());
    
            Criteria criteria = session.createCriteria("censusMasterIngest");
            criteria.add(Example.create(incomingCensus));
            
            try {
            		results = criteria.list();
            } catch (org.hibernate.exception.GenericJDBCException e) {
                   	throw new ReadException(ErrorCodeEnum.HIBERNATE_READ_FAILURE, e, e.getMessage());
            }
            
            if (results.size() < 1) {
                   
                    incomingCensus.setCensusReceivedCount(1);
                    
                    if( censusMasterIngest.getIngestStatus() != null){
                    	status = censusMasterIngest.getIngestStatus();
                    }
                    else if ( 1==censusMasterIngest.getCensusExpectedCount()){
                    	status = CensusSurveyConstant.INGEST_COMPLETE;
                    }
                    
                    //incomingCensus.addElement("ingestStatus").addText(status);
                    incomingCensus.setIngestStatus(status);
                    
                    censusMasterID = (Long)session.save("censusMasterIngest", incomingCensus);
            } else {
                            
                    //String ingestStatus = results.get(0).element("ingestStatus").getText();
                    CensusMasterIngest storedIngest = results.get(0);
                    String ingestStatus = storedIngest.getIngestStatus();
                    
    
                    if(ingestStatus.equals(CensusSurveyConstant.INGEST_PENDING)){
                            //int segmentReceivedCount = Integer.parseInt(results.get(0).element("segmentReceivedCount").getText()) + 1;
                            int segmentReceivedCount = storedIngest.getCensusReceivedCount() + 1;
                            //results.get(0).element("segmentReceivedCount").setText(Integer.toString(segmentReceivedCount));
                            storedIngest.setCensusReceivedCount(segmentReceivedCount);
                            if( censusMasterIngest.getIngestStatus() != null){
                            	status = censusMasterIngest.getIngestStatus();
                            } 
                            //else if (results.get(0).element("segmentReceivedCount").getText().equals(censusMasterIngest.getCensusExpectedCount())){
                            else if (segmentReceivedCount ==censusMasterIngest.getCensusExpectedCount()){
                            	status = CensusSurveyConstant.INGEST_COMPLETE;
                            } 
                            
                            //results.get(0).element("ingestStatus").setText(status);
                            storedIngest.setIngestStatus(status);
                            
                    
                           // System.out.println("DB Element outgoing:" + storedIngest.toString() + "\n");
                            //censusMasterID = results.get(0).elementText("id");
                            censusMasterID = storedIngest.getId();
                            session.update(storedIngest);
                    } 
            }
            
            //just clear the memory before persisting the first batch of insert. It take long time to insert so need this to eliminate racing condition.
            session.flush();
            session.clear();
            
            return censusMasterID;
    }*/


    /**
    * Sets the rules to evaluate to determine if the persistence manager is
    * applicable for the request.
    * 
     * @param rules
    *            The boolean rules to be evaluated.
    */
    public void setRules( List<BooleanRuleInterface> rules )
    {
        this.rules = rules;
    }


    public void setCdsAppName( String cdsAppName )
    {
        this.cdsAppName = cdsAppName;
    }

    /*private void iterateAllElements(List<Element> elementList){
    	
    	Iterator<Element> it = elementList.iterator();
    	while (it.hasNext()){
    		Element rootElement = it.next();
    		String rootName = rootElement.getName();
    		String rootText = rootElement.getText();
    		Iterator<Element> elementIter =  rootElement.elementIterator();
    		while(elementIter.hasNext()){
    			Element element = elementIter.next();
    			String name = element.getName();
    			String text = element.getText();
    			System.out.println("");
    		}
    	}
    
    }*/

    /* ===================Following is for the multi-table relational solution
    @SuppressWarnings("unchecked")
    private void storeModalities(Session session, Element aSurveyResponse) {
                    List<Element> results = null;
    
                    try {
                                                    Element responseModalities = aSurveyResponse.element("modalities");
                                                    Iterator<Element> it =  responseModalities.elementIterator();
    
                                    while (it.hasNext())
                                    {                              
                                                    Element responseModality = (Element) it.next();
                                                    Criteria criteria;
                                                    criteria = session.createCriteria("modality");
                                                    criteria.add(Example.create(responseModality));
                                                    Element aModalitiy;
                                                    
                                                    try {
                                                                    results = criteria.list();
                                                    } catch (org.hibernate.exception.GenericJDBCException e) {
                                                                    throw new ReadException(ErrorCodeEnum.HIBERNATE_READ_FAILURE, e,
                                                                                                    e.getMessage());
                                                    }
    
                                                    if (results.size() < 1) {
                                                                    // Modality doesn't exist
                                                                    aModalitiy = (Element)responseModality.clone();
                                                                    aModalitiy.detach();
                                                                    session.save(aModalitiy);
                                                    }
                                                    else{
                                                                    
                                                                    aModalitiy = results.get(0);
                                                                    aModalitiy.detach();
                                                    }
                                                                    responseModality.add(aModalitiy);
                                                                    responseModality.remove(responseModality.element("modalityType"));
                                                                    responseModality.remove(responseModality.element("modalityName"));
    
                                                    //System.out.println("aModality:" + responseModalities.asXML() + "\n");           
                                    }                              
                    } catch (org.hibernate.exception.GenericJDBCException e) {
                                    throw new ReadException(ErrorCodeEnum.HIBERNATE_READ_FAILURE, e,
                                                                    e.getMessage());
                    }
    }
    
    @SuppressWarnings("unchecked")
    protected void retrieveOrStoreData(Session session, Element response,
                                    String entityName) {
                    List<Element> results = null;
                    Element transitive = response.element(entityName);
                    if(surveyPatient.equalsIgnoreCase(entityName)){
                                    String vendorId = response.element("vendor").elementText("id");
                                    transitive.addElement("vendorID").addText(vendorId);
                    }
    
                    Criteria criteria = session.createCriteria(entityName);
                    criteria.add(Example.create(transitive));
                    try {
                                    results = criteria.list();
                    } catch (org.hibernate.exception.GenericJDBCException e) {
                                    throw new ReadException(ErrorCodeEnum.HIBERNATE_READ_FAILURE, e,
                                                                    e.getMessage());
                    }
                    
                    if (results.size() < 1) {
    
                                    session.save(transitive);
                    } else {
                                    response.remove(transitive);
                                    response.add(results.get(0));
                    }
    }
    
    @SuppressWarnings("unchecked")
    protected void validateAndRetrieveCCFacility(Session session,
                                    Element aSurveyResponse) {
    
                    String incomingFacilityNumber = aSurveyResponse.element("careCoordinator").element("facilityNumber").getText();
                    Element incomingFacility = DocumentHelper.createElement("facility");
                    Element locationElement = DocumentHelper.createElement("location");
                    locationElement.setText(incomingFacilityNumber);
                    incomingFacility.add(locationElement);
                    List<Element> results = null;       
    
                    Criteria criteria = session.createCriteria("facility");
                    criteria.add(Example.create(incomingFacility));
    
                    try {
                                    results = criteria.list();
                    } catch (org.hibernate.exception.GenericJDBCException e) {
                                    throw new ReadException(ErrorCodeEnum.HIBERNATE_READ_FAILURE, e,
                                                                    e.getMessage());
                    }
    
                    if (results.size() != 1) {
                                    throw new ReadException(
                                                                    ErrorCodeEnum.WRITE_REQUEST_CARE_COORDINATOR_FACILITY_INVALID,
                                                                    incomingFacility.elementText("location"));
                    }
                    //add Facility ID to insert in the Care Coordinator table.
                    String facilityId = results.get(0).elementText("id");
                    aSurveyResponse.element("careCoordinator").addElement("facilityID").addText(facilityId);
    }
    
                    @SuppressWarnings("unchecked")
    protected void validateAndRetrieveCensusVendor(Session session,
                                    Element aSurveyResponse) {
                    List<Element> results = null;
                    boolean foundVendor = false;
    
                    Element incomingVendor = aSurveyResponse.element("vendor");
    
                    Element vendorName = incomingVendor.element("name");
                    String vendorNameToStore = vendorName.getText();
    
                    incomingVendor.remove(vendorName);
    
                    Criteria criteria = session.createCriteria("vendor");
                    criteria.add(Example.create(incomingVendor));
                    try {
                                    results = criteria.list();
                    } catch (org.hibernate.exception.GenericJDBCException e) {
                                    throw new ReadException(ErrorCodeEnum.HIBERNATE_READ_FAILURE, e,
                                                                    e.getMessage());
                    }
    
                    if (results.size() < 1) {
                                    // vendor number doesn't exist
                                    throw new ReadException(
                                                                    ErrorCodeEnum.WRITE_REQUEST_SURVEY_VENDOR_NUMBER_INVALID,
                                                                    incomingVendor.element("number").getText());
                    }
    
                    for (Element vendor : results) {
                                    if (vendor.element("name").getText()
                                                                    .equals(vendorNameToStore)) {
                                                    aSurveyResponse.remove(incomingVendor);
                                                    aSurveyResponse.add(vendor);
                                                    foundVendor = true;
                                                    break;
                                    }
                    }
    
                    if (!foundVendor) {
                                    incomingVendor.add(vendorName);
                                    session.save(incomingVendor);
                    }
    }
    ========================================*/

}
