/**
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.geronimo.connector.outbound;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.resource.ResourceException;
import javax.resource.spi.ManagedConnection;
import javax.resource.spi.ManagedConnectionFactory;

/**
 * This pool is the most spec-compliant pool.  It can be used by itself with no partitioning.
 * It is apt to be the slowest pool.
 * For each connection request, it synchronizes access to the pool and asks the
 * ManagedConnectionFactory for a match from among all managed connections.  If none is found,
 * it may discard a random existing connection, and creates a new connection.
 *
 * @version $Rev$ $Date$
 */
public class SinglePoolMatchAllConnectionInterceptor extends AbstractSinglePoolConnectionInterceptor {

    private HashMap pool;

    private int maxSize;

    public SinglePoolMatchAllConnectionInterceptor(final ConnectionInterceptor next,
                                                   int maxSize,
                                                   int minSize,
                                                   int blockingTimeoutMilliseconds,
                                                   int idleTimeoutMinutes) {

        super(next, maxSize, minSize, blockingTimeoutMilliseconds, idleTimeoutMinutes);
        this.maxSize = maxSize;
        pool = new HashMap(maxSize);
    }

    protected void internalGetConnection(ConnectionInfo connectionInfo) throws ResourceException {
        synchronized (pool) {
            if (destroyed) {
                throw new ResourceException("ManagedConnection pool has been destroyed");
            }
            try {
                if (!pool.isEmpty()) {
                    ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
                    ManagedConnectionFactory managedConnectionFactory = mci.getManagedConnectionFactory();
                    ManagedConnection matchedMC =
                            managedConnectionFactory
                            .matchManagedConnections(pool.keySet(),
                                    mci.getSubject(),
                                    mci.getConnectionRequestInfo());
                    if (matchedMC != null) {
                        connectionInfo.setManagedConnectionInfo((ManagedConnectionInfo) pool.get(matchedMC));
                        pool.remove(matchedMC);
                        if (log.isTraceEnabled()) {
                            log.trace("Returning pooled connection " + connectionInfo.getManagedConnectionInfo());
                        }
                        if (connectionCount < minSize) {
                            timer.schedule(new FillTask(connectionInfo), 10);
                        }
                        return;
                    }
                }
                //matching failed or pool is empty
                //if pool is at maximum size, pick a cx to kill
                if (connectionCount == maxSize) {
                    Iterator iterator = pool.entrySet().iterator();
                    ManagedConnectionInfo kill = (ManagedConnectionInfo) ((Map.Entry) iterator.next()).getValue();
                    iterator.remove();
                    ConnectionInfo killInfo = new ConnectionInfo(kill);
                    internalReturn(killInfo, ConnectionReturnAction.DESTROY);
                }
                next.getConnection(connectionInfo);
                connectionCount++;
                if (log.isTraceEnabled()) {
                    log.trace("Returning new connection " + connectionInfo.getManagedConnectionInfo());
                }
                if (connectionCount < minSize) {
                    timer.schedule(new FillTask(connectionInfo), 10);
                }

            } catch (ResourceException e) {
                //something is wrong: rethrow, release permit
                permits.release();
                throw e;
            }
        }
    }

    protected boolean internalReturn(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction) {
        ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
        ManagedConnection mc = mci.getManagedConnection();
        try {
            mc.cleanup();
        } catch (ResourceException e) {
            connectionReturnAction = ConnectionReturnAction.DESTROY;
        }

        boolean wasInPool = false;
        synchronized (pool) {
            // a bit redundant, but this closes a small timing hole...
            if (destroyed) {
                try {
                    mc.destroy();
                }
                catch (ResourceException re) { } // ignore
                return pool.remove(mci.getManagedConnection()) != null;
            }
            if (shrinkLater > 0) {
                //nothing can get in the pool while shrinkLater > 0, so wasInPool is false here.
                connectionReturnAction = ConnectionReturnAction.DESTROY;
                shrinkLater--;
            } else if (connectionReturnAction == ConnectionReturnAction.RETURN_HANDLE) {
                mci.setLastUsed(System.currentTimeMillis());
                pool.put(mci.getManagedConnection(), mci);
                return wasInPool;
            } else {
                wasInPool = pool.remove(mci.getManagedConnection()) != null;
            }
        }
        //we must destroy connection.
        next.returnConnection(connectionInfo, connectionReturnAction);
        connectionCount--;
        return wasInPool;
    }

    protected void internalDestroy() {
        synchronized (pool) {
            Iterator it = pool.keySet().iterator();
            for (; it.hasNext(); ) {
                try {
                    ((ManagedConnection)it.next()).destroy();
                }
                catch (ResourceException re) { } // ignore
                it.remove();
            }
        }
    }

    public int getPartitionMaxSize() {
        return maxSize;
    }

    public int getIdleConnectionCount() {
        return pool.size();
    }

    protected void transferConnections(int maxSize, int shrinkNow) {
        //1st example: copy 0 (none)
        //2nd example: copy 10 (all)
        HashMap oldPool = pool;
        pool = new HashMap(maxSize);
        //since we have replaced pool already, pool.remove will be very fast:-)
        assert oldPool.size() == connectionCount;
        Iterator it = oldPool.entrySet().iterator();
        for (int i = 0; i < shrinkNow; i++) {
            ConnectionInfo killInfo = new ConnectionInfo((ManagedConnectionInfo) ((Map.Entry)it.next()).getValue());
            internalReturn(killInfo, ConnectionReturnAction.DESTROY);
        }
        for (; it.hasNext(); ) {
            Map.Entry entry = (Map.Entry) it.next();
            pool.put(entry.getKey(), entry.getValue());
        }

    }

    protected void getExpiredManagedConnectionInfos(long threshold, ArrayList killList) {
        synchronized (pool) {
            for (Iterator iterator = pool.entrySet().iterator(); iterator.hasNext();) {
                Map.Entry entry = (Map.Entry) iterator.next();
                ManagedConnectionInfo mci = (ManagedConnectionInfo) entry.getValue();
                if (mci.getLastUsed() < threshold) {
                    killList.add(mci);
                }
            }
        }

    }

    protected boolean addToPool(ManagedConnectionInfo mci) {
        boolean added;
        synchronized (pool) {
            connectionCount++;
            added = getPartitionMaxSize() > getIdleConnectionCount();
            if (added) {
                pool.put(mci.getManagedConnection(), mci);
            }
        }
        return added;
    }

}
