/**
 * 
 */


package gov.va.med.cds.audit;


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

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.XPath;

import net.minidev.json.JSONObject;
import net.minidev.json.parser.JSONParser;
import net.minidev.json.parser.ParseException;


/**
 * @author vhaislegberb
 *
 */
public class VhimReadResponseAuditLog
    extends
        AbstractAuditLog
{
    private static final long serialVersionUID = 1L;


    /* (non-Javadoc)
     * @see gov.va.med.cds.audit.AbstractAuditLog#getResponseLength(java.lang.String)
     */
    @SuppressWarnings( "rawtypes" )
    @Override
    protected int getResponseLength( String response )
    {

        int responseLength = 0;
        if ( response == null )
        {
            return responseLength;
        }

        try
        {
            Document document = DocumentHelper.parseText( response );
            Element rootElement = document.getRootElement();

            for ( Iterator patientIterator = rootElement.elementIterator( "patient" ); patientIterator.hasNext(); )
            {
                Element patientElement = ( Element )patientIterator.next();
                responseLength += patientElement.elements( "allergyAssessments" ).size();
                responseLength += patientElement.elements( "intoleranceConditions" ).size();
                responseLength += patientElement.elements( "vitalSignObservationEvents" ).size();
                responseLength += patientElement.elements( "outpatientMedicationPromises" ).size();
                responseLength += patientElement.elements( "labTestPromises" ).size();
            }

            if ( rootElement.element( "patients" ) != null )
            {
                Map<String, String> namespaceUris = new HashMap<String, String>();
                namespaceUris.put( "patientjournaling", "PatientJournaling" );

                for ( Iterator patientIterator = rootElement.element( "patients" ).elementIterator( "patient" ); patientIterator.hasNext(); )
                {
                    Element patientElement = ( Element )patientIterator.next();
                    responseLength += patientElement.selectNodes( "clinicalDocumentEvents/clinicalDocumentEvent" ).size();
                    responseLength += patientElement.selectNodes( "nonVaMedicationEvents/nonVaMedicationEvent" ).size();
                    responseLength += patientElement.selectNodes( "skinTestProcedures/skinTestProcedure" ).size();
                    responseLength += patientElement.selectNodes( "immunizationEvents/immunizationEvent" ).size();
                    responseLength += patientElement.selectNodes( "healthConcerns/healthConcern" ).size();
                    responseLength += patientElement.selectNodes( "outpatientMedicationPromises/outpatientMedicationPromise" ).size();
                    responseLength += patientElement.selectNodes( "labTestPromises/labTestPromise" ).size();
                    responseLength += patientElement.selectNodes( "patientEnteredVitalSigns/patientEnteredVitalSign" ).size();
                    responseLength += patientElement.selectNodes( "calendarEvents/calendarEvent" ).size();
                    responseLength += patientElement.selectNodes( "skillsTracking/skillTracking" ).size();
                    responseLength += patientElement.selectNodes( "goalsTracking/goalTracking" ).size();
                    responseLength += patientElement.selectNodes( "painEvents/painEvent" ).size();
                    responseLength += patientElement.selectNodes( "painReassessments/painReassessment" ).size();
                    responseLength += patientElement.selectNodes( "painAssessments/painAssessment" ).size();
                    responseLength += patientElement.selectNodes( "assessmentDocuments/assessmentDocument" ).size();
                    responseLength += patientElement.selectNodes( "questionnaireResults/questionnaireResult" ).size();
                    responseLength += patientElement.selectNodes( "smartFormDocuments/smartFormDocument" ).size();

                    //GenericObservation 
                    responseLength += getVPRCount( patientElement );

                }
            }

        }
        catch ( DocumentException e )
        {
            throw new IllegalArgumentException( "Invalid document string passed in.", e );
        }

        return responseLength;
    }


    private int getVPRCount( Element patientElement )
        throws DocumentException
    {
        List<Element> genericObsrvations;
        String vprResult;
        Document vprXml;
        JSONParser jsonParser = null;
        JSONObject dataObj = null;
        JSONObject innerObj = null;
        JSONObject response = null;
        int recordCnt = 0;

        genericObsrvations = patientElement.selectNodes( "genericObservations/genericObservation/observationValue" );
        if ( genericObsrvations != null && genericObsrvations.size() > 0 )
        {
            for ( Element el : genericObsrvations )
            {
                vprResult = el.getText();
                if ( vprResult.startsWith( "<" ) )
                {
                    vprXml = DocumentHelper.parseText( vprResult );

                    Element e = ( Element )vprXml.selectSingleNode( "//radiologyExams" );

                    if ( null == e )
                    {
                        e = ( Element )vprXml.selectSingleNode( "//flags" );
                    }

                    recordCnt += Integer.parseInt( e.attributeValue( "total" ) );
                }
                else
                {
                    jsonParser = new JSONParser( -1 );
                    try
                    {
                        response = ( JSONObject )jsonParser.parse( vprResult );
                    }
                    catch ( ParseException e )
                    {
                        throw new IllegalArgumentException( "Invalid json string passed in.", e );
                    }

                    dataObj = ( JSONObject )response.get( "data" );
                    if ( dataObj != null )
                    {
                        recordCnt += ( ( Integer )dataObj.get( "totalItems" ) ).intValue();
                    }
                    else
                    {
                        dataObj = ( JSONObject )response.get( "results" );
                        if ( dataObj != null )
                        {
                            innerObj = ( JSONObject )dataObj.get( "radiologyExams" );

                            if ( null == innerObj )
                            {
                                innerObj = ( JSONObject )dataObj.get( "flags" );
                            }

                            recordCnt += ( ( Integer )innerObj.get( "total" ) ).intValue();
                        }
                    }

                }

            }
        }
        return recordCnt;
    }
}
