/*
 * Copyright (c) 1998, 2021 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, 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, 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, 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
     */
    protected void setConnectionsAvailable(Vector connectionsAvailable) {
        this.connectionsAvailable = connectionsAvailable;
    }

    /**
     *  INTERNAL:
     *  Set the list of connections being used.
     */
    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
     */
    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 = {getMinNumberOfConnections(), 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);
    }
}
