/*
 * Copyright (c) 2010, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2010, 2015 Dies Koper (Fujitsu) 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:
//     Created Jan 10, 2010 - Dies Koper (Fujitsu), patterned after SybaseTransactionIsolationListener
//        bug 288715: Tests: Several Core LRG tests hang on Symfoware.
package org.eclipse.persistence.testing.framework;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.sessions.SessionEvent;
import org.eclipse.persistence.sessions.SessionEventAdapter;

/*
 * <p>Apache Derby and Symfoware in general are configured to use transaction isolation level
 * READ_COMMITTED or SERIALIZABLE.</p>
 * That causes a few tests to hang, or fail with an error message saying that the table is locked
 * (depending on a setting on the database side): these tests begin transaction, update a row,
 * then (before the transaction has been committed) attempt to read the row through another connection.
 *
 * To allow these reads to go through (and read the uncommitted data) connection isolation level
 * should be temporary switched to READ_UNCOMMITTED.
 *
 * This class switches the acquired connection to READ_UNCOMMITTED and then sets back the original
 * isolation level before connection is released.
 *
 * Note that for the above scenario only read connections require level READ_UNCOMMITTED.
 *
 * @author Dies Koper
 */
public class TransactionIsolationLevelSwitchListener extends SessionEventAdapter {
    private final String statement;
    Map<Connection, String> connections = new HashMap<Connection, String>();

    public TransactionIsolationLevelSwitchListener(DatabasePlatform platform) {
        if (platform.isDerby()) {
            statement = "set isolation ";
        } else if (platform.isMaxDB()) {
            statement = "set transaction isolation level ";
        } else {
            statement = "";
        }
    }

    @Override
    public void postAcquireConnection(SessionEvent event) {
        Connection conn = ((DatabaseAccessor) event.getResult())
                .getConnection();
        Statement stmt1 = null;
        String isolationLevel = "";
        try {
            int i = conn.getTransactionIsolation();
            switch (i) {
            case 1:
                isolationLevel = "READ UNCOMMITTED";
                break;
            case 2:
                isolationLevel = "READ COMMITTED";
                break;
            case 4:
                isolationLevel = "REPEATABLE READ";
                break;
            case 8:
                isolationLevel = "SERIALIZABLE";
                break;
            }
            if (i > 0) {
                // If conn1 began transaction and updated the row (but hasn't
                // committed the transaction yet),
                // then conn2 should be able to read the original (not updated)
                // state of the row.
                // Without this conn2 reading the row hangs on Symfoware.
                stmt1 = conn.createStatement();
                stmt1.execute(statement + "READ UNCOMMITTED");

                connections.put(conn, isolationLevel);
            }
        } catch (SQLException sqlException) {
            throw new TestProblemException("postAcquireConnection failed. ",
                    sqlException);
        } finally {
            if (stmt1 != null) {
                try {
                    stmt1.close();
                } catch (SQLException ex) {
                    // Ignore
                }
            }
        }
    }

    @Override
    public void preReleaseConnection(SessionEvent event) {
        Connection conn = ((DatabaseAccessor) event.getResult())
                .getConnection();
        Statement stmt = null;
        try {
            String isolationLevel = connections.remove(conn);
            if (isolationLevel != null) {
                // reset the original transaction isolation.
                stmt = conn.createStatement();
                stmt.execute(statement + isolationLevel);
                stmt.close();
            }
        } catch (SQLException sqlException) {
            throw new TestProblemException("preReleaseConnection failed. ",
                    sqlException);
        } finally {
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException ex) {
                    // Ignore
                }
            }
        }
    }
}
