/*
 * 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.internal.jpa.transaction;

import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.util.Vector;
import java.sql.*;
import javax.transaction.xa.XAResource;
import jakarta.transaction.*;
import org.eclipse.persistence.exceptions.TransactionException;
import org.eclipse.persistence.internal.jpa.jdbc.ConnectionProxyHandler;
import org.eclipse.persistence.internal.jpa.jdbc.DataSourceImpl;

/**
 * Implementation of JTA Transaction class. The guts of the tx logic
 * is contained in this class.
 *
 * Currently support is limited to enlisting only a single tx data source
 */
@Deprecated
public class TransactionImpl implements Transaction {
    // Set by client-induced rollback marking
    boolean markedForRollback;

    // Used to maintain the tx status
    int status;

    // Collection of Synchronization listeners
    Vector listeners;

    // The transactional connection we use
    Connection connection;
    static Class<?> proxyClass = Proxy.getProxyClass(Connection.class.getClassLoader(), new Class[] { Connection.class });

    // The enlisted data source
    DataSourceImpl dataSource;

    /***** Static constants *****/

    // Cribbed from java.transaction.Status
    public static final int STATUS_ACTIVE = 0;
    public static final int STATUS_MARKED_ROLLBACK = 1;
    public static final int STATUS_PREPARED = 2;
    public static final int STATUS_COMMITTED = 3;
    public static final int STATUS_ROLLEDBACK = 4;
    public static final int STATUS_UNKNOWN = 5;
    public static final int STATUS_NO_TRANSACTION = 6;
    public static final int STATUS_PREPARING = 7;
    public static final int STATUS_COMMITTING = 8;
    public static final int STATUS_ROLLING_BACK = 9;

    // Set this to true for debugging of afterCompletion exceptions
    public static boolean DUMP_AFTER_COMPLETION_ERRORS = true;

    /************************/
    /***** Internal API *****/
    /************************/
    private void debug(String s) {
        System.out.println(s);
    }

    /*
     * Constructor invoked and new instance created on tx begin
     */
    public TransactionImpl() {
        markedForRollback = false;
        status = STATUS_ACTIVE;
        listeners = new Vector();
    }

    /*
     * Lazily allocate the connection. This will be used
     * by the data source if in a transaction.
     */
    public Connection getConnection(DataSourceImpl ds, String user, String password) throws SQLException {
        // We don't have a datasource connection yet, so allocate one
        if (connection == null) {
            debug("TxImpl - allocating new connection");
            dataSource = ds;
            connection = ds.internalGetConnection(user, password);
            connection.setAutoCommit(false);
        } else {
            // We already have a connection. Make sure the data sources are the same.
            if (ds.getName() != dataSource.getName()) {
                throw TransactionException.multipleResourceException();
            }
        }

        //  return connection;
        // Allocate and return a proxy for the connection
        debug("TxImpl - creating connection proxy");
        Connection proxyConnection = null;
        try {
            InvocationHandler handler = new ConnectionProxyHandler(connection);
            proxyConnection = (Connection)proxyClass.getConstructor(new Class[] { InvocationHandler.class }).newInstance(new Object[] { handler });
        } catch (Exception ex) {
            throw TransactionException.internalProxyException(ex);
        }
        return proxyConnection;
    }

    /*
     * Invoke afterCompletion callbacks.
     * If DUMP_AFTER_COMPLETION_ERRORS flag is set then dump
     * the exceptions to System.out, otherwise swallow them.
     *
     * NOTE: In either case it will not affect the outcome
     * of the transaction.
     */
    public void invokeAfterCompletion() {
        // Call all of the afterCompletion callbacks
        debug("TxImpl - invoking afterCompletion");
        int i;
        int j;
        for (i = 0, j = listeners.size(); i < j; i++) {
            try {
                ((Synchronization)listeners.elementAt(i)).afterCompletion(status);
            } catch (Throwable t) {
                if (DUMP_AFTER_COMPLETION_ERRORS) {
                    t.printStackTrace(System.out);
                }
            }
        }
    }

    /*
     * Rollback the transaction on the connection.
     */
    public void rollbackConnection() throws SQLException {
        if (connection != null) {
            debug("TxImpl - rolling back connection");
            status = STATUS_ROLLING_BACK;
            connection.rollback();
            status = STATUS_ROLLEDBACK;
        }
    }

    /*
     * Commit the transaction on the connection.
     */
    public void commitConnection() throws SQLException {
        if (connection != null) {
            debug("TxImpl - committing connection");
            status = STATUS_COMMITTING;
            connection.commit();
            status = STATUS_COMMITTED;
        }
    }

    /*
     * Clean up after everything is over
     */
    public void cleanup() {
        debug("TxImpl - cleanup");
        if (connection != null) {
            try {
                connection.close();
            } catch (Exception ex) {
            }

            // Ignore
            connection = null;
        }
        status = STATUS_NO_TRANSACTION;
    }

    /*************************************/
    /***** Supported Transaction API *****/
    /*************************************/
    @Override
    public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, IllegalStateException, SystemException {
        Exception error = null;

        debug("TxImpl - commit");
        // Make sure we are allowed to proceed
        switch (status) {
        case STATUS_ACTIVE:// This is the normal case - do nothing
            break;
        case STATUS_MARKED_ROLLBACK: {
            // Tx was marked for rollback by the user, error
            error = new ExceptionFactory().txMarkedForRollbackException();
            break;
        }
        default:// Tx in some other state, error
            throw new ExceptionFactory().invalidStateException(status);
        }

        // Call beforeCompletion callback.
        if (error == null) {
            try {
                debug("TxImpl - invoking beforeCompletion");
                int i;
                int j;
                for (i = 0, j = listeners.size(); i < j; i++) {
                    ((Synchronization)listeners.elementAt(i)).beforeCompletion();
                }
            } catch (Exception ex) {
                error = ex;
                status = STATUS_ROLLING_BACK;
                debug("TxImpl - error in beforeCompletion: " + ex);
            }
        }

        // Now if we didn't get any errors then commit the connection
        if ((error == null) && (status == STATUS_ACTIVE)) {
            try {
                commitConnection();
            } catch (Exception ex) {
                error = ex;
            }
        } else {
            try {
                rollbackConnection();
            } catch (Exception ex) {
                error = ex;
            }
        }

        // Whether we were successful or not, call afterCompletion and clean up
        invokeAfterCompletion();
        cleanup();

        // Throw any error that may have occurred at any point in the commit
        if (error != null) {
            throw new ExceptionFactory().newSystemException(error);
        }
    }

    @Override
    public int getStatus() throws SystemException {
        return status;
    }

    @Override
    public void registerSynchronization(Synchronization synchronization) throws RollbackException, IllegalStateException, SystemException {
        debug("TxImpl - registering sync listener: " + synchronization);
        listeners.add(synchronization);
    }

    @Override
    public void rollback() throws IllegalStateException, SystemException {
        Exception error = null;

        debug("TxImpl - rollback");
        try {
            rollbackConnection();
        } catch (Exception ex) {
            error = ex;
        }

        // Call afterCompletion callback and clean up
        invokeAfterCompletion();
        cleanup();

        // Throw any error that may have occurred while rolling back
        if (error != null) {
            throw new ExceptionFactory().newSystemException(error);
        }
    }

    @Override
    public void setRollbackOnly() throws IllegalStateException, SystemException {
        debug("TxImpl - setRollbackOnly");
        status = STATUS_MARKED_ROLLBACK;
    }

    /*****************************************/
    /***** NOT supported Transaction API *****/
    /*****************************************/
    @Override
    public boolean enlistResource(XAResource xaresource) throws RollbackException, IllegalStateException, SystemException {
        return false;
    }

    @Override
    public boolean delistResource(XAResource xaresource, int i) throws IllegalStateException, SystemException {
        return false;
    }
}
