/**
 * 
 */


package gov.va.med.repositories.fpds.filter;


import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;

import javax.ws.rs.core.MultivaluedMap;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.springframework.util.StringUtils;


/**
 * @author DNS   egberb
 *
 */
public class HmpReadRequestDom4jFilterBuilder
    implements
        FilterBuilder
{
    public static final String REQUEST_ID = "requestId";
    public static final String CLIENT_NAME = "clientName";
    public static final String EX_AF = "excludedAssigningFacility";
    public static final String EX_AA = "excludedAssigningAuthority";
    public static final String EX_AI = "excludedIdentity";


    @Override
    public String createFilter( String filterId, String patientId, String domain, MultivaluedMap<String, String> queryParamsMap )
    {

        return createXml( filterId, patientId, queryParamsMap.getFirst( CLIENT_NAME ), domain, queryParamsMap.getFirst( EX_AI ),
                        queryParamsMap.getFirst( EX_AF ), queryParamsMap.getFirst( EX_AA ), queryParamsMap );
    }


    @SuppressWarnings( { "rawtypes", "unchecked" } )
    private String createXml( String filterIdentifier, String patientIdentifier, String clientName, String domain, String excludedIdenitifier,
                    String excludedAssigningFacility, String excludedAssigningAuthority, MultivaluedMap<String, String> qryParamMap )
    {
        Namespace filterNamespace = DocumentHelper.createNamespace( "filter", "Filter" );
        Element filterElement = DocumentHelper.createElement( DocumentHelper.createQName( "filter", filterNamespace ) );
        filterElement.addAttribute( "vhimVersion", "Vhim_4_00" );

        filterElement.add( DocumentHelper.createElement( "filterId" ).addText( filterIdentifier ) );
        filterElement.add( DocumentHelper.createElement( "clientName" ).addText( clientName ) );

        String clientRqstInitiationTime = null;
        if ( qryParamMap.containsKey( "clientRequestInitiationTime" ) )
        {
            ArrayList lst = ( ArrayList<String> )qryParamMap.get( "clientRequestInitiationTime" );
            clientRqstInitiationTime = ( String )lst.get( 0 );
            if ( !StringUtils.hasText( clientRqstInitiationTime ) )
            {
                filterElement.add( DocumentHelper.createElement( "clientRequestInitiationTime" ).addText(
                                DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) ) );
            }
            else
            {
                filterElement.add( DocumentHelper.createElement( "clientRequestInitiationTime" ).addText( clientRqstInitiationTime ) );
            }
        }
        else
        {
            filterElement.add( DocumentHelper.createElement( "clientRequestInitiationTime" ).addText(
                            DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) ) );
        }

        Element pidElement = DocumentHelper.createElement( "patients" );
        pidElement.addElement( "NationalId" ).addText( patientIdentifier );

        if ( StringUtils.hasText( excludedAssigningFacility ) )
        {
            Element excludIdsElement = DocumentHelper.createElement( "excludeIdentifiers" );
            excludIdsElement.addElement( "assigningAuthority" ).addText( excludedAssigningAuthority );
            excludIdsElement.addElement( "assigningFacility" ).addText( excludedAssigningFacility );
            if ( StringUtils.hasText( excludedIdenitifier ) )
            {
                excludIdsElement.addElement( "identity" ).addText( excludedIdenitifier );
            }

            pidElement.add( excludIdsElement );
        }
        filterElement.add( pidElement );

        Element entryPointElement = DocumentHelper.createElement( "entryPointFilter" );
        entryPointElement.addAttribute( "queryName", "queryName" );
        entryPointElement.addElement( "domainEntryPoint" ).addText( "GenericObservation" );
        String startDate = qryParamMap.getFirst( "startDate" );
        String endDate = qryParamMap.getFirst( "endDate" );

        if ( StringUtils.hasText( startDate ) )
        {
            entryPointElement.addElement( "startDate" ).addText( startDate );
        }

        if ( StringUtils.hasText( endDate ) )
        {
            entryPointElement.addElement( "endDate" ).addText( endDate );
        }

        Map.Entry entry = null;
        String key = null;
        ArrayList<String> lst = null;
        Iterator entries = qryParamMap.entrySet().iterator();
        Element otherQryParamsElement = DocumentHelper.createElement( "otherQueryParameters" );
        Element additionalParamsElement = null;
        String value = null;

        while ( entries.hasNext() )
        {
            entry = ( Map.Entry )entries.next();
            key = ( String )entry.getKey();

            if ( !key.equals( "requestId" ) && !key.startsWith( "excluded" ) && !key.equals( "clientName" ) && !key.equals( "startDate" )
                            && !key.equals( "endDate" ) && !key.equals( "clientRequestInitiationTime" ) && !key.equals("filterId") )
            {
                lst = ( ArrayList<String> )entry.getValue();
                value = ( String )lst.get( 0 );
                additionalParamsElement = DocumentHelper.createElement( "additionalParameter" );
                additionalParamsElement.addAttribute( "name", key );
                additionalParamsElement.addAttribute( "type", "text" );
                additionalParamsElement.add( DocumentHelper.createElement( "value" ).addText( value ) );

                otherQryParamsElement.add( additionalParamsElement );
            }
        }

        entryPointElement.add( otherQryParamsElement );
        filterElement.add( entryPointElement );

        return filterElement.asXML();
    }
}
