

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


import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

import javax.ws.rs.core.MultivaluedMap;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.stream.StreamSource;

import net.sf.saxon.TransformerFactoryImpl;

import org.dom4j.Document;
import org.dom4j.io.DocumentResult;
import org.dom4j.io.DocumentSource;
import org.springframework.core.io.ClassPathResource;


/**
 * 
 * Base abstract filter builder parent class - defines common functionality and abstract methods for specific domains
 * 
 * @author DNS   talbom
 *
 */
public abstract class AbstractBaseFilterBuilder
    implements
        FilterBuilder
{

    //TODO - NEED TO REMOVE EXCLUDE AAS
    protected static final List<String> STANDARD_FILTER_PARAMS = Arrays.asList( new String[] { "requestId", "clientName", "clientRequestInitiationTime",
                    "startDate", "endDate", "resolvedIdentifier", "resolvedAssigningFacility", "resolvedAssigningAuthority","excludeIdentifier", "nationalId" } );
    
	public static final String EX_AI = "excludeIdentifier";

	public static final String RS_ID = "resolvedIdentifier";

	public static final String ICN = "nationalId";

	public static final String SEPARATOR = "-";

	protected static final String CLIENT_REQUEST_TIME = "clientRequestInitiationTime";

    protected Templates filterTransformerTemplate;


    @Override
    public String createFilter( String filterId, String patientId, String domain, MultivaluedMap<String, String> queryParamsMap )
    {
        DocumentResult result = new DocumentResult();
        Transformer transformer = null;

        if ( filterTransformerTemplate == null )
        {
            throw new FilterBuilderException( "This filter build requires an XSLT style-sheet in order to build the filter."
                            + " Make sure to set the filter transformer template resource location before calling the createFilter method." );
        }

        try
        {
            transformer = filterTransformerTemplate.newTransformer();
            Document filterDocument = buildRequestParamsDocument( filterId, domain, patientId, queryParamsMap );
            DocumentSource source = new DocumentSource( filterDocument );
            transformer.transform( source, result );
        }
        catch ( Exception e )
        {
            throw new FilterBuilderException( "Error transforming filter.", e );
        }

        return result.getDocument().asXML();
    }


    public void setFilterTransformerTemplate( String filterTransformerTemplate )
        throws TransformerConfigurationException,
            IOException
    {
        InputStream templateInputStream = null;
        StreamSource templateStreamSource = null;

        try
        {
            org.springframework.core.io.Resource templateResource = new ClassPathResource( filterTransformerTemplate );
            templateInputStream = templateResource.getInputStream();
            templateStreamSource = new StreamSource( templateInputStream );
            this.filterTransformerTemplate = new TransformerFactoryImpl().newTemplates( templateStreamSource );
        }
        finally
        {
            if ( templateInputStream != null )
            {
                templateInputStream.close();
            }
        }
    }


    abstract Document buildRequestParamsDocument( String filter, String domain, String patient, MultivaluedMap<String, String> additionalParams );

}
