

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


import gov.va.med.repositories.fpds.webservice.FederatingPatientRecordRestService;

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

import javax.ws.rs.core.MultivaluedMap;

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


/**
 * This class uses an XSLT style-sheet to generate the filter from the incoming request.
 */
public class VprSubscribeUpdatesCancelRequestXsltFilterBuilder
    extends
        AbstractBaseFilterBuilder
{

    Document buildRequestParamsDocument( String filter, String domain, String patient, MultivaluedMap<String, String> additionalParams )
    {
        String command = additionalParams.getFirst( "command" );
        
    	Document filterDocument = DocumentHelper.createDocument( DocumentHelper.createElement( "requestData" ) );
        filterDocument.getRootElement().add( DocumentHelper.createElement( "filterId" ).addText( filter ) );

        if ( !StringUtils.hasLength( patient ) )
        {
            patient = StringUtils.trimTrailingWhitespace( additionalParams.getFirst( ICN ) );

            if ( StringUtils.hasLength( patient ) )
            {
                filterDocument.getRootElement().add( DocumentHelper.createElement( "patientId" ).addText( patient ) );
            }
        }

        filterDocument.getRootElement().add( DocumentHelper.createElement( "domainEntryPoint" ).addText( domain ) );
        filterDocument.getRootElement().add( DocumentHelper.createElement( "additionalParams" ) );

        String[] content = null;
        List<String> dfnList = additionalParams.get( RS_ID );
        for ( String key : additionalParams.keySet() )
        {
            if ( StringUtils.hasLength( additionalParams.getFirst( key ) ) )
            {
                if ( !key.startsWith( "_" ) ) // ignore any query parameters that start with an underscore character.
                {
                    if ( STANDARD_FILTER_PARAMS.contains( key ) )
                    {
                        if ( key.equals( "clientRequestInitiationTime" ) )
                        {
                            String clientInitiationTime = ( String )additionalParams.getFirst( key );
                            if ( !StringUtils.hasText( clientInitiationTime ) )
                            {
                                filterDocument.getRootElement().add(
                                                DocumentHelper.createElement( "clientRequestInitiationTime" ).addText(
                                                                DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format( new Date() ) ) );
                            }
                            else
                            {
                                filterDocument.getRootElement().add(
                                                DocumentHelper.createElement( "clientRequestInitiationTime" ).addText( clientInitiationTime ) );
                            }
                        }
                        else if ( key.equals( RS_ID ) && !StringUtils.hasLength( patient ) )
                        {

                            for ( String dfn : dfnList )
                            {
                            	content = dfn.split( SEPARATOR );
                            	Element el = DocumentHelper.createElement( "resolvedIdentifier" );
                            	
                            	if(command.equals(FederatingPatientRecordRestService.GETUPDATES_COMMAND) || command.equals(FederatingPatientRecordRestService.RESET_COMMAND)){
                            		/*
                            		 * the index size is larger for non patient because the first element begins with a minus sign -999, 
                            		 * this is the NonPatient and we know it has been fully structured within the webservice -999-SOMESITEID-USVHA
                            		 * so we do not need to check for index values - they will exist
                            		*/
                            		el.add( DocumentHelper.createElement( "identifier" ).addText( "-999" ) );
                            		el.add( DocumentHelper.createElement( "assigningFacility" ).addText( content[2] ) );
                            		el.add( DocumentHelper.createElement( "assigningAuthority" ).addText( content[3] ) );
                            	}
                            	else if ( content != null && content.length > 0 )
                                {
                                    if ( content[0] != null || content[0].length() > 0 )
                                    {
                                        el.add( DocumentHelper.createElement( "identifier" ).addText( content[0] ) );
                                        
                                        if ( content.length > 1)
                                        {
                                            el.add( DocumentHelper.createElement( "assigningFacility" ).addText( content[1] ) );
                                        }
                                        if ( content.length > 2)
                                        {
                                            el.add( DocumentHelper.createElement( "assigningAuthority" ).addText( content[2] ) );
                                        }
                                    }

                                }
                                filterDocument.getRootElement().add( el );
                            }

                        }
                        else
                        {
                            filterDocument.getRootElement().add( DocumentHelper.createElement( key ).addText( additionalParams.getFirst( key ) ) );
                        }
                    }
                    else
                    {
                        filterDocument.getRootElement()
                                        .element( "additionalParams" )
                                        .add( DocumentHelper.createElement( "entry" ).addAttribute( "key", key )
                                                        .addAttribute( "value", additionalParams.getFirst( key ) ) );
                    }
                }
            }
        }

        return filterDocument;
    }
}
