

package gov.va.med.cds.response.organizer;


import gov.va.med.cds.exception.ErrorCodeEnum;
import gov.va.med.cds.response.organizer.strategy.OrderingStrategyInterface;

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


public class ResponseOrganizer
    implements
        ResponseOrganizerInterface
{

    private static final String DOMAIN_ENTRY_POINT = "domainEntryPoint";
    private static final String ENTRY_POINT_FILTER = "entryPointFilter";
    private static final String XQUERY_EXPRESSION = "xqueryExpression";
    private static final String ORDER_BY = "orderBy";

    OrderingStrategyInterface orderingStrategy;


    @Override
    /**
     * Organizes/sorts response XML based on filter instructions.
     */
    public Document organize( String xmlFilterRequest, Document responseDocument )
    {
        Element entryPointFilter = getEntyPointFilterElement( xmlFilterRequest );

        if ( isSortNeeded( entryPointFilter ) )
        {
            // XQuery expression validated during filter validation, no additional validation needed.
            String sortExpression = entryPointFilter.element( ORDER_BY ).elementText( XQUERY_EXPRESSION );
            String domainEntryPoint = entryPointFilter.elementText( DOMAIN_ENTRY_POINT );
            responseDocument = orderingStrategy.order( sortExpression, domainEntryPoint, responseDocument );
        }
        return responseDocument;
    }


    /**
     * Creates dom4j document and extract entryPointFilter element, handles exceptions
     * Validation of individual elements not required, filter has been validated already. 
     * @param xmlFilterRequest
     * @return
     */
    private Element getEntyPointFilterElement( String xmlFilterRequest )
    {
        try
        {
            Document a = DocumentHelper.parseText( xmlFilterRequest );
            return a.getRootElement().element( ENTRY_POINT_FILTER );
        }
        catch ( DocumentException e )
        {
            throw new ResponseOrganazerException( ErrorCodeEnum.FILTER_PARSER_DOM_EXCEPTION, e, xmlFilterRequest );
        }
    }

    /**
     * Checks if orderBy element is present
     * @param entryPointFilter
     * @return
     */
    private boolean isSortNeeded( Element entryPointFilter )
    {
        return entryPointFilter.element( ORDER_BY ) != null;
    }


    /**
     * @return the orderingStrategy
     */
    public OrderingStrategyInterface getOrderingStrategy( )
    {
        return orderingStrategy;
    }


    /**
     * @param orderingStrategy the orderingStrategy to set
     */
    public void setOrderingStrategy( OrderingStrategyInterface orderingStrategy )
    {
        this.orderingStrategy = orderingStrategy;
    }

}
