package ca.sebastiendionne.grizzly.server;


import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;

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

import ca.sebastiendionne.grizzly.manager.IEchoManager;

import com.sun.grizzly.SelectorHandler;
import com.sun.grizzly.util.ByteBufferFactory;

/**
 * This class contain the logic to parse the request
 * from the client.
 * 
 * There is one Thread by client connected.
 * 
 * @author Sebastien Dionne
 *
 */
public class ClientConnectionHandler implements Comparable<ClientConnectionHandler> {
	
	private static final Logger s_logger = LoggerFactory.getLogger(ClientConnectionHandler.class);
	
	protected SelectionKey f_key;
	protected SelectorHandler f_selectorHandler;
	protected IEchoManager manager;
	
	/**
	 * manage the connection with the client
	 * @param manager le QuoteManager
	 */
	public ClientConnectionHandler(IEchoManager server, SelectionKey key, SelectorHandler selectorHandler){
		manager = server;
		f_key = key;
		f_selectorHandler = selectorHandler;
	}
	
	
	/**
	 * close the client connection
	 */
	public synchronized void close(){
		
		if(s_logger.isDebugEnabled()){
			s_logger.debug("ClientConnection close");
		}
		
		 // No more bytes can be read from the channel
		f_selectorHandler.getSelectionKeyHandler().cancel(f_key);
		manager.removeFromCache(f_key);
	}

	public SelectionKey getKey() {
		return f_key;
	}

	public SelectorHandler getSelectorHandler() {
		return f_selectorHandler;
	}


	public void setKey(SelectionKey f_key) {
		this.f_key = f_key;
	}

	public void setSelectorHandler(SelectorHandler handler) {
		f_selectorHandler = handler;
	}
	
	/**
	 * Need this function because of the SkipList.
	 */
	public int compareTo(ClientConnectionHandler obj0) {
		return obj0.getKey().toString().compareTo(this.getKey().toString());
	}

	
	
	@Override
	public int hashCode() {
		return getKey().toString().hashCode();
	}


	@Override
	public boolean equals(Object obj) {
		
		if(obj==null){
			return false;
		}
		
		if(!(obj instanceof ClientConnectionHandler)){
			return false;
		}
		
		ClientConnectionHandler objCH = (ClientConnectionHandler)obj;
		// la KEY ne peut pas etre NULL !!!
		return objCH.getKey().toString().equals(getKey().toString());
	}
	
	public void sendToClient(String message) {
		
		if(message==null){
			return;
		}
		
		ByteBuffer writeBuffer = ByteBufferFactory.allocateView(message.getBytes().length, false);
		
		writeBuffer.put(message.getBytes());
		
		writeBuffer.flip();
		
		try {
			if(getKey().isValid()){
				getSelectorHandler().getAsyncQueueWriter().write(getKey(),writeBuffer);
			} else {
				// le client n'est pas connecte
				close();
			}
			
		} catch (IOException e) {
			s_logger.error("sendToClient", e);
		}

	}
	
	
}
