/*
 * Copyright (c) 1998, 2019 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.sessions.server;

import java.util.*;

import org.eclipse.persistence.internal.databaseaccess.*;
import org.eclipse.persistence.sessions.Login;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.internal.localization.*;
import org.eclipse.persistence.logging.SessionLog;

/**
 * <p>
 * <b>Purpose</b>: Used to specify how connection should be pooled in a server session.
 * @see ServerSession
 */
public class ConnectionPool {
    protected static final String MONITOR_HEADER = "Info:ConnectionPool:";

    protected boolean isConnected;
    protected int maxNumberOfConnections;
    protected int minNumberOfConnections;
    protected int initialNumberOfConnections;
    protected int waitTimeout;
    protected List<Accessor> connectionsAvailable;
    protected List<Accessor> connectionsUsed;
    protected Login login;
    protected String name;
    protected ServerSession owner;
    protected volatile boolean checkConnections;
    protected volatile long timeOfDeath;
    protected volatile long deadCheckTime;
    protected volatile boolean isDead;
    protected List<String> failoverConnectionPools;

    public static final long DEAD_CHECK_TIME = 1000 * 60 * 10; // 10 minutes.
    public static final int MAX_CONNECTIONS = 32;
    public static final int MIN_CONNECTIONS = 32;
    public static final int INITIAL_CONNECTIONS = 1;
    public static final int WAIT_TIMEOUT = 180000; // 3 minutes.

    /**
     * PUBLIC:
     * A connection pool is used to specify how connection should be pooled in a server session.
     */
    public ConnectionPool() {
        this(null, null, null);
    }

    /**
     * PUBLIC:
     * A connection pool is used to specify how connection should be pooled in a server session.
     */
    public ConnectionPool(String name, Login login, ServerSession owner) {
        this(name, login, INITIAL_CONNECTIONS, MIN_CONNECTIONS, MAX_CONNECTIONS, owner);
    }

    /**
     * PUBLIC:
     * A connection pool is used to specify how connection should be pooled in a server session.
     */
    public ConnectionPool(String name, Login login, int minNumberOfConnections, int maxNumberOfConnections, ServerSession owner) {
        this(name, login, Math.min(INITIAL_CONNECTIONS, minNumberOfConnections), minNumberOfConnections, maxNumberOfConnections, owner);
    }

    /**
     * PUBLIC:
     * A connection pool is used to specify how connection should be pooled in a server session.
     */
    public ConnectionPool(String name, Login login, int initialNumberOfConnections, int minNumberOfConnections, int maxNumberOfConnections, ServerSession owner) {
        this.login = login;
        this.owner = owner;
        this.name = name;
        this.maxNumberOfConnections = maxNumberOfConnections;
        this.minNumberOfConnections = minNumberOfConnections;
        this.initialNumberOfConnections = initialNumberOfConnections;
        this.deadCheckTime = DEAD_CHECK_TIME;
        this.waitTimeout = WAIT_TIMEOUT;
        this.checkConnections = false;
        this.failoverConnectionPools = new ArrayList<>();
        resetConnections();
    }

    /**
     * INTERNAL:
     * The connection pool is dead fail over to the fail-over pool.
     */
    public Accessor failover() {
        if ((this.timeOfDeath + this.deadCheckTime) < System.currentTimeMillis()) {
            // Retry database to see if it is back up.
            this.isDead = false;
            return acquireConnection();
        } else {
            for (String poolName : this.failoverConnectionPools) {
                ConnectionPool pool = this.owner.getConnectionPool(poolName);
                if (!pool.isDead()) {
                    if (this.owner.shouldLog(SessionLog.FINEST, SessionLog.CONNECTION)) {
                        Object[] args = new Object[2];
                        args[0] = this.name;
                        args[1] = poolName;
                        this.owner.log(SessionLog.FINEST, SessionLog.CONNECTION, "failover", args);
                    }
                    return pool.acquireConnection();
                }
            }
            throw QueryException.failoverFailed(this.name);
        }
    }

    /**
     * INTERNAL:
     * Wait until a connection is available and allocate the connection for the client.
     */
    public synchronized Accessor acquireConnection() throws ConcurrencyException {
        // Check for dead database and fail-over.
        if (this.isDead) {
            return failover();
        }
        // PERF: Using direct variable access to minimize concurrency bottleneck.
        while (this.connectionsAvailable.isEmpty()) {
            if ((this.connectionsUsed.size() + this.connectionsAvailable.size()) < this.maxNumberOfConnections) {
                Accessor connection = null;
                try {
                    connection = buildConnection();
                } catch (RuntimeException failed) {
                    if (!this.failoverConnectionPools.isEmpty()) {
                        this.isDead = true;
                        this.timeOfDeath = System.currentTimeMillis();
                        this.owner.logThrowable(SessionLog.WARNING, SessionLog.SQL, failed);
                        return acquireConnection();
                    } else {
                        throw failed;
                    }
                }
                this.connectionsUsed.add(connection);
                if (this.owner.isInProfile()) {
                    this.owner.updateProfile(MONITOR_HEADER + this.name, Integer.valueOf(this.connectionsUsed.size()));
                }
                if (this.owner.shouldLog(SessionLog.FINEST, SessionLog.CONNECTION)) {
                    Object[] args = new Object[1];
                    args[0] = this.name;
                    this.owner.log(SessionLog.FINEST, SessionLog.CONNECTION, "acquire_connection", args, connection);
                }
                return connection;
            }
            try {
                wait(this.waitTimeout);// Notify is called when connections are released.
            } catch (InterruptedException exception) {
                throw ConcurrencyException.waitFailureOnClientSession(exception);
            }
        }

        int connectionSize = this.connectionsAvailable.size();
        // Always used the last connection to avoid shift list and to use "hot" connection.
        Accessor connection = this.connectionsAvailable.remove(connectionSize-1);
        if (this.checkConnections) {
            // EclipseLink has encountered a problem with a connection where the database no longer responded
            // We need to now ensure that the failure was specific to that connection or we need to empty
            // the pool of dead connections in the case of a database failover.
            while (connectionSize >= 0) {
                if (this.owner.getLogin().isConnectionHealthValidatedOnError() && this.owner.getServerPlatform().wasFailureCommunicationBased(null, connection, this.owner)) {
                    try {
                        //connection failed connect test
                        connection.closeConnection();
                    } catch (Exception ex){
                        //ignore
                    } finally {
                        connection.releaseCustomizer();
                    }
                    if (this.connectionsAvailable.isEmpty()) {
                        this.checkConnections = false;
                        //we have emptied out all connections so let's have the connection pool build more
                        return acquireConnection();
                    } else {
                        //test next connection
                        --connectionSize;
                        connection = this.connectionsAvailable.remove(connectionSize-1);
                    }
                } else {
                    //connection was good use it.  And make sure we stop testing connections
                    this.checkConnections = false;
                    break;
                }
            }
        }
        this.connectionsUsed.add(connection);
        if (this.owner.isInProfile()) {
            this.owner.updateProfile(MONITOR_HEADER + this.name, Integer.valueOf(this.connectionsUsed.size()));
        }
        if (this.owner.shouldLog(SessionLog.FINEST, SessionLog.CONNECTION)) {
            Object[] args = new Object[1];
            args[0] = this.name;
            this.owner.log(SessionLog.FINEST, SessionLog.CONNECTION, "acquire_connection", args, connection);
        }
        return connection;
    }

    /**
     * INTERNAL:
     * Create a new connection, accessors are used as connections.
     */
    protected Accessor buildConnection() {
        Accessor connection = this.login.buildAccessor();
        connection.setPool(this);
        connection.connect(this.login, this.owner);

        return connection;
    }

    /**
     * INTERNAL:
     * returns the connections currently available for use in the pool
     */
    public List<Accessor> getConnectionsAvailable() {
        return connectionsAvailable;
    }

    /**
     *  Return a list of the connections that are being used.
     *  @return java.util.Vector
     **/
    protected List<Accessor> getConnectionsUsed() {
        return connectionsUsed;
    }

    /**
     * PUBLIC:
     * Return the login used to create connections.
     */
    public Login getLogin() {
        return login;
    }

    /**
     * PUBLIC:
     * Return the maximum number of connections allowed.
     * If all connections are in use, a new connection will be created until the maximum size is reach.
     * Only the minimum number of connections will be pooled, if the pool is between the min and max size
     * the connection will be disconnected when returned to the pool.
     * Typically it is desirable to have the min and max connections the same to avoid connects and disconnects.
     * When the max is reached clients must wait for a connection to become available.
     */
    public int getMaxNumberOfConnections() {
        return maxNumberOfConnections;
    }

    /**
     * PUBLIC:
     * Return the minimum number of connections.
     * If all connections are in use, a new connection will be created until the maximum size is reach.
     * Only the minimum number of connections will be pooled, if the pool is between the min and max size
     * the connection will be disconnected when returned to the pool.
     * Typically it is desirable to have the min and max connections the same to avoid connects and disconnects.
     */
    public int getMinNumberOfConnections() {
        return minNumberOfConnections;
    }

    /**
     * PUBLIC:
     * Return the name of this pool.
     * Pools are identified by name to allow multiple connection pools.
     */
    public String getName() {
        return name;
    }

    /**
     *  Return the ServerSession that is the owner of this connection pool.
     *  @return org.eclipse.persistence.sessions.server.ServerSession
     */
    protected ServerSession getOwner() {
        return owner;
    }

    /**
     * INTERNAL:
     * Return the total number of connections currently in use.
     */
    public int getTotalNumberOfConnections() {
        return getConnectionsUsed().size() + getConnectionsAvailable().size();
    }

    /**
     * INTERNAL:
     * Wait until a connection is avaiable and allocate the connection for the client.
     */
    public boolean hasConnectionAvailable() {
        return !getConnectionsAvailable().isEmpty();
    }

    /**
     * INTERNAL:
     * Return if this pool has been connected to the database.
     */
    public boolean isConnected() {
        return isConnected;
    }

    /**
     * INTERNAL:
     * Checks for a conflict between pool's type and pool's login
     */
    public boolean isThereConflictBetweenLoginAndType() {
        return getLogin().shouldUseExternalConnectionPooling();
    }

    /**
     * INTERNAL:
     * Add the connection as single that a new connection is available.
     */
    public synchronized void releaseConnection(Accessor connection) throws DatabaseException {
        if (this.owner.shouldLog(SessionLog.FINEST, SessionLog.CONNECTION)) {
            Object[] args = new Object[1];
            args[0] = this.name;
            this.owner.log(SessionLog.FINEST, SessionLog.CONNECTION, "release_connection", args, connection);
        }
        connection.reset();

        this.connectionsUsed.remove(connection);

        if (!connection.isValid()) {
            this.checkConnections = true;
            try {
                connection.disconnect(this.owner);
            } catch (DatabaseException ex) {
                //this is an invalid connection so expect an exception.
            }
        } else {
            if ((this.connectionsUsed.size() + this.connectionsAvailable.size()) < this.minNumberOfConnections) {
                this.connectionsAvailable.add(connection);
            } else {
                connection.disconnect(getOwner());
            }
        }
        if (this.owner.isInProfile()) {
            this.owner.updateProfile(MONITOR_HEADER + this.name, Integer.valueOf(this.connectionsUsed.size()));
        }
        notify();
    }

    /**
     * INTERNAL:
     * Reset the connections on shutDown and when the pool is started.
     */
    public void resetConnections() {
        this.connectionsUsed = new Vector();
        this.connectionsAvailable = new Vector();
        this.checkConnections = false;
        this.isDead = false;
        this.timeOfDeath = 0;
    }

    /**
     * INTERNAL:
     * This method is called to indicate that all available connections should be checked.
     */
    public void setCheckConnections() {
        this.checkConnections = true;
    }

    /**
     *  INTERNAL:
     *  Set this list of connections available
     *  @param connectionsAvailable
     */
    protected void setConnectionsAvailable(Vector connectionsAvailable) {
        this.connectionsAvailable = connectionsAvailable;
    }

    /**
     *  INTERNAL:
     *  Set the list of connections being used.
     *  @param connectionsUsed
     */
    protected void setConnectionsUsed(Vector connectionsUsed) {
        this.connectionsUsed = connectionsUsed;
    }

    /**
     * INTERNAL:
     * Set if this pool has been connected to the database.
     */
    public void setIsConnected(boolean isConnected) {
        this.isConnected = isConnected;
    }

    /**
     * PUBLIC:
     * Set the login used to create connections.
     */
    public void setLogin(Login login) {
        this.login = login;
    }

    /**
     * PUBLIC:
     * Return the initial number of connections allowed.
     * This is the number of connections connected on startup.
     */
    public int getInitialNumberOfConnections() {
        return initialNumberOfConnections;
    }

    /**
     * PUBLIC:
     * Set the initial number of connections allowed.
     * This is the number of connections connected on startup.
     * The default is 1.
     */
    public void setInitialNumberOfConnections(int initialNumberOfConnections) {
        this.initialNumberOfConnections = initialNumberOfConnections;
    }

    /**
     * PUBLIC:
     * Set the maximum number of connections allowed.
     * If all connections are in use, a new connection will be created until the maximum size is reach.
     * Only the minimum number of connections will be pooled, if the pool is between the min and max size
     * the connection will be disconnected when returned to the pool.
     * Typically it is desirable to have the min and max connections the same to avoid connects and disconnects.
     * When the max is reached clients must wait for a connection to become available.
     * The default is 32.
     */
    public void setMaxNumberOfConnections(int maxNumberOfConnections) {
        this.maxNumberOfConnections = maxNumberOfConnections;
    }

    /**
     * PUBLIC:
     * Set the minimum number of connections.
     * If all connections are in use, a new connection will be created until the maximum size is reach.
     * Only the minimum number of connections will be pooled, if the pool is between the min and max size
     * the connection will be disconnected when returned to the pool.
     * Typically it is desirable to have the min and max connections the same to avoid connects and disconnects.
     * The default is 32.
     */
    public void setMinNumberOfConnections(int minNumberOfConnections) {
        this.minNumberOfConnections = minNumberOfConnections;
    }

    /**
     * PUBLIC:
     * Set the name of this pool.
     * Pools are identified by name to allow multiple connection pools.
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     *  Set the ServerSession that owns this connection pool
     *  @param owner
     */
    protected void setOwner(ServerSession owner) {
        this.owner = owner;
    }

    /**
     * INTERNAL:
     * Disconnect all connections.
     */
    public synchronized void shutDown() {
        setIsConnected(false);

        for (Iterator iterator = getConnectionsAvailable().iterator(); iterator.hasNext();) {
            try {
                ((Accessor)iterator.next()).disconnect(getOwner());
            } catch (DatabaseException exception) {
                // Ignore.
            }
        }

        for (Iterator iterator = getConnectionsUsed().iterator(); iterator.hasNext();) {
            try {
                ((Accessor)iterator.next()).disconnect(getOwner());
            } catch (DatabaseException exception) {
                // Ignore.
            }
        }
        resetConnections();
    }

    /**
     * INTERNAL:
     * Allocate the minimum connections.
     */
    public synchronized void startUp() {
        if (isConnected()) {
            return;
        }
        for (int index = getInitialNumberOfConnections(); index > 0; index--) {
            getConnectionsAvailable().add(buildConnection());
        }

        setIsConnected(true);
    }

    /**
     * INTERNAL:
     * return a string representation of this connection pool
     */
    @Override
    public String toString() {
        Object[] args = { Integer.valueOf(getMinNumberOfConnections()), Integer.valueOf(getMaxNumberOfConnections()) };
        return Helper.getShortClassName(getClass()) + ToStringLocalization.buildMessage("min_max", args);
    }

    /**
     * PUBLIC:
     * Return the time in milliseconds to wait for a available connection.
     * If the wait time is exceeded and exception will occur.
     * The default is 180000 or 3 minutes.
     * A value of 0 means wait forever.
     */
    public int getWaitTimeout() {
        return waitTimeout;
    }

    /**
     * PUBLIC:
     * Set the time in milliseconds to wait for an available connection.
     * If the wait time is exceeded an exception will occur.
     * The default is 180000 or 3 minutes.
     * A value of 0 means wait forever.
     */
    public void setWaitTimeout(int waitTimeout) {
        this.waitTimeout = waitTimeout;
    }

    /**
     * ADVANCED:
     * Return if the connection pool's database is down, and failover should be used.
     */
    public boolean isDead() {
        return isDead;
    }

    /**
     * ADVANCED:
     * Set if the connection pool's database is down, and failover should be used.
     */
    public void setIsDead(boolean isDead) {
        this.isDead = isDead;
    }

    /**
     * PUBLIC:
     * Return the list of connection pools to used if this pool database goes down.
     * The failover pools should be a clustered, replicated or backuped database.
     */
    public List<String> getFailoverConnectionPools() {
        return failoverConnectionPools;
    }

    /**
     * PUBLIC:
     * Set the list of connection pools to used if this pool database goes down.
     * The failover pools should be a clustered, replicated or backuped database.
     */
    public void setFailoverConnectionPools(List<String> failoverConnectionPools) {
        this.failoverConnectionPools = failoverConnectionPools;
    }

    /**
     * PUBLIC:
     * Add the connection pool to used if this pool database goes down.
     * The failover pools should be a clustered, replicated or backuped database.
     */
    public boolean addFailoverConnectionPool(String poolName) {
        return this.failoverConnectionPools.add(poolName);
    }
}
