

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


import gov.va.med.cds.persistence.hibernate.common.VistaPointInTimeUserTypeNoTimezone;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

import org.springframework.util.StringUtils;


public class RpcXmlParamStringBuilder
    extends
        RpcParamStringBuilder
{

    public static final String DOMAIN = "domain";
    public static final String STOP = "stop";
    public static final String START = "start";
    public static final String MAX = "max";
    public static final String ID = "id";
    public static final String PATIENT_ID = "patientId";
    public static final String TEXT = "text";


    @Override
    public String build( Map<String, String> queryParams )
    {
        StringBuffer sbParams = new StringBuffer();

        Map<String, String> paramsMap = new HashMap();
        paramsMap.putAll( queryParams );

        LinkedHashMap<String, String> argsMap = setArgsMap( paramsMap );
        Iterator<String> argsIter = argsMap.keySet().iterator();

        VistaPointInTimeUserTypeNoTimezone vistaDateTimeConvertor = new VistaPointInTimeUserTypeNoTimezone();

        String paramValue = null;
        String value = null;
        while ( argsIter.hasNext() )
        {
            String paramName = argsIter.next();

            //restriction of XML RPC - expects values in a predefined order 'I:<DFN>|I:<Domain>|I:<Fromdate>|I:<ToDate>|I:<Max>|I:<ID>              
            if ( paramName.equals( START ) || paramName.equals( STOP ) )
            {
                value = argsMap.get( paramName );
                if ( StringUtils.hasLength( value ) )
                {
                    paramValue = vistaDateTimeConvertor.convertToCacheDate( value );

                }
                else
                {
                    paramValue = null;
                }
            }
            else
            {
                paramValue = argsMap.get( paramName );
            }

            //sbParams.append( String.format( "I:\"%s\"|", paramValue) );
            sbParams.append( String.format( getArgFormat(), paramValue ) );

            sbParams.append( "|" );

        }

        Iterator<Map.Entry<String, String>> qryParamIter = paramsMap.entrySet().iterator();
        while ( qryParamIter.hasNext() )
        {
            Map.Entry<String, String> entry = qryParamIter.next();
            //sbParams.append( "|" );

            //A:FILTER("%s")=%s
            if(!entry.getKey().equals( "toJson" ))
            {
            sbParams.append( String.format( getArgWithFunctionFormat(), entry.getKey(), entry.getValue() ) );
            sbParams.append( "|" );
            }
        }

        sbParams.append( this.vistaFixedEnvParam );

        return sbParams.toString();
    }


    private LinkedHashMap<String, String> setArgsMap( Map<String, String> qParams )
    {
        LinkedHashMap<String, String> argsMap = new LinkedHashMap<String, String>();
        //predefined I: order of XML RPC
        argsMap.put( PATIENT_ID, null );
        argsMap.put( DOMAIN, null );
        argsMap.put( START, null );
        argsMap.put( STOP, null );
        argsMap.put( MAX, null );
        argsMap.put( ID, null );

        Iterator<String> iter = qParams.keySet().iterator();

        int j = 0;
        while ( iter.hasNext() )
        {
            String paramName = iter.next();

            if ( argsMap.containsKey( paramName ) )
            {
                argsMap.put( paramName, qParams.get( paramName ) );
                iter.remove();
            }
            if ( paramName.equals( "command" ) )
            {
                iter.remove();
            }
        }

        return argsMap;

    }


    @Override
    public String getRpcPatientArgName( )
    {
        return this.patientIdParamName;
    }

}
