package org.mortbay.jetty.client;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;

import org.mortbay.io.Buffer;
import org.mortbay.io.nio.NIOBuffer;
import org.mortbay.jetty.AbstractBuffers;

/**
 * Http connection pool for pooling connections and managing sets of mapped
 * sockets to http destination addresses.
 * 
 * @author Greg Wilkins
 * @author Matthew Purland
 */
public class HttpConnectionPool extends AbstractBuffers
{
    private boolean _useDirectBuffers=true;
    private Map<InetSocketAddress, HttpDestination> _destinations=new HashMap<InetSocketAddress, HttpDestination>();

    /* ------------------------------------------------------------------------------- */
    public HttpConnection getConnection(InetSocketAddress remote, boolean ssl, boolean blockForIdle) throws UnknownHostException, IOException
    {
        if (remote==null)
            throw new UnknownHostException("Remote socket address cannot be null.");

        synchronized (_destinations)
        {
            // TODO separate map for ssl?
            HttpDestination destination=_destinations.get(remote);

            if (destination == null ) 
            {
                destination = new HttpDestination(this,remote);
                _destinations.put(remote,destination);
            }
            return destination.getConnection(ssl,blockForIdle);
        }
    }

    protected HttpConnection newConnection(SocketAddress remote, boolean ssl, boolean blockForIdle)
    {
        return null;
        // HttpConnection connection = new HttpConnection();
    }

    /**
     * Get whether the connector can use direct NIO buffers.
     */
    public boolean getUseDirectBuffers()
    {
        return _useDirectBuffers;
    }

    /**
     * Set to use NIO direct buffers.
     * 
     * @param direct
     *            If True (the default), the connector can use NIO direct
     *            buffers. Some JVMs have memory management issues (bugs) with
     *            direct buffers.
     */
    public void setUseDirectBuffers(boolean direct)
    {
        _useDirectBuffers=direct;
    }

    /**
     * Create a new NIO buffer. If using direct buffers, it will create a direct
     * NIO buffer, other than an indirect buffer.
     */
    @Override
    protected Buffer newBuffer(int size)
    {
        Buffer buf=null;
        if (size==getHeaderBufferSize())
            buf=new NIOBuffer(size,NIOBuffer.INDIRECT);
        else
            buf=new NIOBuffer(size,_useDirectBuffers?NIOBuffer.DIRECT:NIOBuffer.INDIRECT);
        return buf;
    }

}
