package ca.sebastiendionne.grizzly.filter;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ca.sebastiendionne.grizzly.manager.IEchoManager;
import ca.sebastiendionne.grizzly.queue.QueueItem;
import ca.sebastiendionne.grizzly.server.ClientConnectionHandler;

import com.sun.grizzly.Context;
import com.sun.grizzly.ProtocolFilter;
import com.sun.grizzly.ProtocolParser;
import com.sun.grizzly.Context.AttributeScope;
import com.sun.grizzly.util.AttributeHolder;
import com.sun.grizzly.util.WorkerThread;

public class EchoQueryManagerFilter implements ProtocolFilter {
	
	private static final Logger s_logger = LoggerFactory.getLogger(EchoQueryManagerFilter.class);
	
	private static final String CLIENT_CONNECTION_HANDLER_ATTR = "connection-handler";
	private IEchoManager manager;

    public EchoQueryManagerFilter(IEchoManager server) {
    	manager = server;
    }

    public boolean execute(Context context) throws IOException {
        String query = (String) context.removeAttribute(ProtocolParser.MESSAGE);

        if(query==null || query.trim().length()==0){
        	return false;
        }
        
        if(s_logger.isDebugEnabled()){
        	s_logger.debug("Query = " + query);
        }

        // on va chercher le ClientConnectionHandler
        ClientConnectionHandler clientConnectionHandler = retrieveConnectionHandler(context);
        
        manager.addToQueue(new QueueItem(clientConnectionHandler, query));
        
        return true;
    }

    public boolean postExecute(Context context) throws IOException {
        return true;
    }
    
    /**
     * Retourne le ClientConnectionHandler si il est dans le contexte.  S'il n'est pas présent, il faut l'ajouter
     * @param context Grizzly Context
     * @return ClientConnectionHandler
     */
    private ClientConnectionHandler retrieveConnectionHandler(Context context) {
        ClientConnectionHandler clientConnectionHandler = null;

        AttributeHolder connectionAttrs = context.getAttributeHolderByScope(AttributeScope.CONNECTION);
        if (connectionAttrs == null) {
        	WorkerThread workerThread = (WorkerThread) Thread.currentThread(); // Detach the current Thread data.
            connectionAttrs = workerThread.getAttachment();
            // Attach it to the SelectionKey so the it can be resumed later.
            context.getSelectionKey().attach(connectionAttrs);
        } else {
        	clientConnectionHandler = (ClientConnectionHandler) connectionAttrs.getAttribute(CLIENT_CONNECTION_HANDLER_ATTR);
        }
        
        if (clientConnectionHandler == null) {
            clientConnectionHandler = new ClientConnectionHandler(manager, context.getSelectionKey(), context.getSelectorHandler());
            connectionAttrs.setAttribute(CLIENT_CONNECTION_HANDLER_ATTR, clientConnectionHandler);
            
            //add to cache
            manager.addToCache(context.getSelectionKey(), clientConnectionHandler);
        }

        return clientConnectionHandler;
    }
    
}

