/**
 *
 */


package gov.va.med.cds.persistence;


import gov.va.med.cds.filter.EntryFilterInterface;
import gov.va.med.cds.filter.ParameterMapInterface;
import gov.va.med.cds.filter.QueryParameter;
import gov.va.med.cds.persistence.hibernate.VistaGenericStoredProcedureQueryWork;
import gov.va.med.cds.persistence.hibernate.rpc.RpcParamStringBuilderInterface;
import gov.va.med.cds.response.strategy.VistaGenericStoredProcedureSingleResponseStrategyInterface;
import gov.va.med.cds.template.generated.JaxBMarshallerUnmarshallerInterface;

import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.hibernate.Session;


/**
 * @author vhaislegberb
 *
 * Creates a specialized query work object that that knows how to build
 * a VistA Generic Stored Procedure request.
 */
public class VistaGenericStoredProcedureBasedQueryStrategy
    extends
        VistaStoredProcedureBasedQueryStrategy
{
    protected static final Log LOGGER = LogFactory.getLog( VistaGenericStoredProcedureBasedQueryStrategy.class );

    private String username;
    private String password;
    private byte[] key;
    private Map<String, RpcParamStringBuilderInterface> rpcBuilderMap;
    private VistaGenericStoredProcedureSingleResponseStrategyInterface vistaGenericResponseStrategy;
    private static final String XML = "xml";
    private static final String COMMAND = "command";


    @Override
    protected QueryWorkInterface createQueryWork( Session session, QueryAssociationInterface queryAssociation, EntryFilterInterface entryFilter,
                    List<String> personIdentifiers, Class<?> pointInTimeUserType, String siteId, JaxBMarshallerUnmarshallerInterface marshallerUnmarshaller )
    {

        RpcParamStringBuilderInterface rpcBuilder = getRpcStringBuilder( entryFilter );

//        VistaGenericStoredProcedureQueryWork queryWork = new VistaGenericStoredProcedureQueryWork( session, queryAssociation, entryFilter,
//                        personIdentifiers, parameterTransformerMap, queryMap, vistaGenericResponseStrategy, applicationName, siteId, username,
//                        password, rpcBuilder );
        VistaGenericStoredProcedureQueryWork queryWork = new VistaGenericStoredProcedureQueryWork( session, queryAssociation, entryFilter,
                        personIdentifiers, parameterTransformerMap, queryMap, vistaGenericResponseStrategy, applicationName, siteId, username,
                        password, key, rpcBuilder );
//		if ( LOGGER.isDebugEnabled() )
//		{
			LOGGER.debug( "VistaGenericStoredProcedureBasedQueryStrategy.createQueryWork(...username, password, key):" + username + ", " + password + ", " + key );
//		}
        queryWork.setTemplateTimeoutMap( templateTimeoutMap );
        queryWork.setQueryMap( queryMap );
        queryWork.setPooledConnectionUnwrapper( pooledConnectionUnwrapper );

        return queryWork;
    }


    private RpcParamStringBuilderInterface getRpcStringBuilder( EntryFilterInterface entryFilter )
    {
        String command = extractCommandParameter( entryFilter );
        RpcParamStringBuilderInterface rpcBuilder = rpcBuilderMap.get( command );

        return rpcBuilder;
    }


    public void setUsername( String username )
    {
        this.username = username;
    }


    public void setPassword( String password )
    {
        this.password = password;
    }


    public void setKey( String aKey )
    {
        this.key = aKey.getBytes();
    }


    public void setRpcBuilderMap( Map<String, RpcParamStringBuilderInterface> rpcBuilderMap )
    {
        this.rpcBuilderMap = rpcBuilderMap;
    }


    public void setVistaGenericResponseStrategy( VistaGenericStoredProcedureSingleResponseStrategyInterface vistaGenericResponseStrategy )
    {
        this.vistaGenericResponseStrategy = vistaGenericResponseStrategy;
    }


    protected String extractCommandParameter( EntryFilterInterface entryFilter )
    {

        ParameterMapInterface parameterMap = entryFilter.getAdditionalParametersMap();
        QueryParameter<?> queryParameter = parameterMap.getParameterValue( COMMAND );

        String command = null;
        if ( queryParameter != null )
        {
            if ( queryParameter.getValue().equals( XML ) )
            {
                command = XML;
            }
            else
            {
                command = ( String )queryParameter.getValue();
            }
        }

        return command;

    }

}
