/*
 * Copyright (c) 1998, 2020 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:
//     05/28/2008-1.0M8 Andrei Ilitchev
//        - New file introduced for bug 224964: Provide support for Proxy Authentication through JPA.
package org.eclipse.persistence.testing.framework.oracle;

import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;

import oracle.jdbc.pool.OracleDataSource;

import org.eclipse.persistence.sessions.JNDIConnector;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.internal.sessions.AbstractSession;

import org.eclipse.persistence.testing.framework.TestProblemException;

// Intended usage:
// 1.1 Obtains a session from the TestExecutor, logs it out, and keeps;
// 1.2 Using the original session's login and the passed parameters
// creates session that uses externalConnectionPools;
// 1.3 Logs the new session into TestExecutor so that it could be used by tests.
// 2.1 After done with the new session - kill it, shutdown all the data sources created for it;
// 2.2 Login the original session and set it back into TestExecutor.
//// Example: to create a new DatabaseSession that use externalConnectionPooling:
// SessionExchange exchange = new SessionExchange();
// testExecutor.setSession(exchange.createDatabaseSession((DatabaseSession)testExecutor.getSession()), true);
//// after the testing with the new session is completed:
// testExecutor.setSession(exchange.returnOriginalSession());

public class SessionExchanger {
    // indicates whether the original session should be disconnected
    public boolean shouldLogoutOriginalSession = true;
    // indicates whether the new session should be connected
    public boolean shouldLoginNewSession = true;

    DatabaseSession originalSession;
    DatabaseSession newSession;
    boolean hasLoggedOutOriginalSession;
    OracleDataSource dataSource;

    // pass the original session and params for the new one:
    //   useDatabaseSession - "true" means new session is DatabaseSession; "false" - ServerSession;
    //   useExternalConnectionPooling - indicates whether the new session use external connection pooling or not.
    // returns the new session
    public DatabaseSession createNewSession(DatabaseSession originalSession, boolean useDatabaseSession, boolean useExternalConnectionPooling) {
        return createNewSession(originalSession, useDatabaseSession, useExternalConnectionPooling, null, null);
    }

    // additional property parameters:
    //   loginProperties - if not null set into the new session's login;
    //   propertyProperties - if not null set into the new session;
    // returns the new session
    public DatabaseSession createNewSession(DatabaseSession originalSession, boolean useDatabaseSession, boolean useExternalConnectionPooling, Properties loginProperties, Map sessionProperties) {
        if(useExternalConnectionPooling) {
            return createNewSession(originalSession, useDatabaseSession, useExternalConnectionPooling, loginProperties, sessionProperties, -1, -1, -1, -1);
        } else {
            return createNewSession(originalSession, useDatabaseSession, useExternalConnectionPooling, loginProperties, sessionProperties, 2, 2, 2, 2);
        }
    }

    // additional min / max parameters used only in case of ServerSession:
    //   in external pooling case only minWriteConnection and maxWriteConnection used - they determine the min / max number of connections in the created data source,
    //        pass -1 value for minWriteConnection and/or maxWriteConnection if no min and/or max number of connections should be set in the data source.
    //   in internal pooling case the min / max values used for write and read connection pools.
    // returns the new session
    public DatabaseSession createNewSession(DatabaseSession originalSession, boolean useDatabaseSession, boolean useExternalConnectionPooling, Properties loginProperties, Map sessionProperties,
                                            int minWriteConnections, int maxWriteConnections, int minReadConnections, int maxReadConnections)
    {
        setup(originalSession);
        DatabaseLogin login = cloneAndSetDataSource(originalSession.getLogin(), useExternalConnectionPooling, minWriteConnections, maxWriteConnections);
        if(useDatabaseSession) {
            newSession = new DatabaseSessionImpl(login);
        } else {
            if(useExternalConnectionPooling) {
                newSession = new ServerSession(login);
            } else {
                newSession = new ServerSession(login, minWriteConnections, minWriteConnections);
            }
            if(!useExternalConnectionPooling) {
                ServerSession ss = (ServerSession)newSession;
                if(ss.getReadConnectionPool().getMaxNumberOfConnections() != maxReadConnections) {
                    ss.getReadConnectionPool().setMaxNumberOfConnections(maxReadConnections);
                }
                if(ss.getReadConnectionPool().getMinNumberOfConnections() != minReadConnections) {
                    ss.getReadConnectionPool().setMinNumberOfConnections(minReadConnections);
                }
            }
        }
        setProperties(loginProperties, sessionProperties);
        newSession.setSessionLog(originalSession.getSessionLog());
        newSession.setLogLevel(originalSession.getLogLevel());
        if(shouldLoginNewSession) {
            newSession.login();
        }
        return newSession;
    }

    // disconnects the temporary session, closes its datasource (if any);
    // in case the original session was disconnected in setup - reconnects it;
    // returns the original session
    public DatabaseSession returnOriginalSession() {
        try {
            clearNewSession();
            return originalSession;
        } finally {
            try {
                if(originalSession != null && hasLoggedOutOriginalSession) {
                    hasLoggedOutOriginalSession = false;
                    originalSession.login();
                }
            } finally {
                originalSession = null;
            }
        }
    }

    public boolean isBusy() {
        return newSession != null;
    }

    void setup(DatabaseSession originalSession) {
        if(isBusy()) {
            throw new TestProblemException("SessionExchanger: new session has been already created");
        }
        this.originalSession = originalSession;
        if(shouldLogoutOriginalSession) {
            if(originalSession.isConnected()) {
                originalSession.logout();
                hasLoggedOutOriginalSession = true;
            }
        }
    }

    void clearNewSession() {
        try {
            if(newSession != null) {
                if(newSession.isConnected()) {
                    newSession.logout();
                }
            }
        } finally {
            newSession = null;
            if(dataSource != null) {
                try {
                    dataSource.close();
                } catch (SQLException ex) {
                    throw new TestProblemException("Exception thrown while closing OracleDataSource:\n", ex);
                } finally {
                    dataSource = null;
                }
            }
        }
    }

    DatabaseLogin cloneAndSetDataSource(DatabaseLogin login, boolean useExternalConnectionPooling, int minConnections, int maxConnections) {
        DatabaseLogin cloneLogin = (DatabaseLogin)login.clone();
        if(useExternalConnectionPooling) {
            createDataSource(login.getConnectionString(), minConnections, maxConnections);
            cloneLogin.setConnector(new JNDIConnector(dataSource));
            cloneLogin.setUsesExternalConnectionPooling(true);
        }
        return cloneLogin;
    }

    void setProperties(Properties loginProperties, Map sessionProperties) {
        if(loginProperties != null) {
            newSession.getLogin().setProperties(loginProperties);
        }
        if(sessionProperties != null) {
            ((AbstractSession)newSession).setProperties(sessionProperties);
        }
    }

    // create a data source using the supplied connection string
    void createDataSource(String connectionString, int minConnections, int maxConnections) {
        try {
            dataSource = new OracleDataSource();
            Properties props = new Properties();
            if(minConnections >= 0) {
                props.setProperty("MinLimit", Integer.toString(minConnections));
                props.setProperty("InitialLimit", Integer.toString(minConnections));
            }
            if(maxConnections >= 0) {
                props.setProperty("MaxLimit", Integer.toString(maxConnections));
            }
            if(!props.isEmpty()) {
                dataSource.setConnectionCacheProperties(props);
            }
        } catch (SQLException ex) {
            throw new TestProblemException("Failed to create OracleDataSource with " + connectionString + ".\n", ex);
        }
        dataSource.setURL(connectionString);
    }
}
