/*
 * 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
//     10/24/2017-3.0 Tomas Kraus
//       - 526419: Modify EclipseLink to reflect changes in JTA 1.1.
package org.eclipse.persistence.transaction;

import jakarta.transaction.*;

import org.eclipse.persistence.exceptions.TransactionException;

/**
 * <p>
 * <b>Purpose</b>: TransactionController implementation for JTA 1.0
 * <p>
 * <b>Description</b>: Implements the required behavior for controlling JTA 1.0
 * transactions. Specific JTA implementations may need to extend this class
 * when special controller behavior is necessary.
 * <p>
 * The JTA TransactionManager must be obtained and set on the
 * instance in order for a Synchronization listener to be registered against
 * the transaction. This can be done either by extending this class and defining
 * acquireTransactionManager() to return the manager for the server, or by using
 * this class and explicitly calling the setTransactionManager() method on it
 * after the fact.
 * e.g.
 *           TransactionManager mgr = controller.jndiLookup("java:comp/TransactionManager");
 *           controller.setTransactionManager(mgr);
 * <p>
 * If a different listener needs to be used for synchronization, the
 * SynchronizationListenerFactory should be set on the controller instance.
 * The listener subclass should implement the factory interface, so that
 * setting the factory is simply a matter of assigning an instance of the
 * listener.
 * e.g.
 *          controller.setSynchronizationListenerFactory(
 *              new DifferentServerSynchronizationListener());
 *
 * The default listener factory creates instances of JTATransactionListener.
 *
 * @see JTASynchronizationListener
 * @see AbstractTransactionController
 */
public class JTATransactionController extends AbstractTransactionController {

    // Allows transaction manager to be set statically.
    protected static TransactionManager defaultTransactionManager;

    // Primary point of integration with JTA
    protected TransactionManager transactionManager;

    /**
     * PUBLIC:
     * Return a new controller for use with a JTA 1.0 compliant TransactionManager.
     */
    public JTATransactionController() {
        super();
        this.listenerFactory = new JTASynchronizationListener();
        try {
            this.transactionManager = acquireTransactionManager();
        } catch (Exception ex) {
            throw TransactionException.errorObtainingTransactionManager(ex);
        }
    }

    /**
     * PUBLIC:
     * Return a new controller for use with a JTA 1.0 compliant TransactionManager.
     */
    public JTATransactionController(TransactionManager transactionManager) {
        super();
        this.listenerFactory = new JTASynchronizationListener();
        this.transactionManager = transactionManager;
    }

    /**
     * INTERNAL:
     * Register the specified synchronization listener with the given active
     * transaction.
     *
     * @param listener The synchronization listener created for this transaction
     * @param txn The active transaction for which notification is being requested
     */
    @Override
    protected void registerSynchronization_impl(AbstractSynchronizationListener listener, Object txn) throws Exception {
        ((Transaction)txn).registerSynchronization(listener);
    }

    /**
     * INTERNAL:
     * Return the active external transaction, or null if none is currently
     * active for this thread.
     *
     * @return The active transaction object or id, or null if no transaction is active
     */
    @Override
    protected Object getTransaction_impl() throws Exception {
        return getTransactionManager().getTransaction();
    }

    /**
     * INTERNAL:
     * Return a key for the specified external transaction object.
     * The key is just something that can be inserted into a hashtable (must support
     * hashCode() and equals() methods).
     *
     * @param transaction The transaction to which the returned key applies (may be null)
     * @return A key for the passed in transaction, or null if no transaction specified
     */
    @Override
    protected Object getTransactionKey_impl(Object transaction) throws Exception {
        // Use the transaction itself as the key
        return transaction;
    }

    /**
     * INTERNAL:
     * Return the transaction status as an object. We will pass around Integers that
     * wrap the int JTA status values.
     *
     * @return The current transaction status
     */
    @Override
    protected Object getTransactionStatus_impl() throws Exception {
        return getTransactionManager().getStatus();
    }

    /**
     * INTERNAL:
     * Begin an external transaction.
     */
    @Override
    protected void beginTransaction_impl() throws Exception {
        getTransactionManager().begin();
    }

    /**
     * INTERNAL:
     * Commit the external transaction.
     */
    @Override
    protected void commitTransaction_impl() throws Exception {
        getTransactionManager().commit();
    }

    /**
     * INTERNAL:
     * Roll back the external transaction.
     */
    @Override
    protected void rollbackTransaction_impl() throws Exception {
        getTransactionManager().rollback();
    }

    /**
     * INTERNAL:
     * Mark the external transaction for rollback.
     */
    @Override
    protected void markTransactionForRollback_impl() throws Exception {
        getTransactionManager().setRollbackOnly();
    }

    /**
     * INTERNAL:
     * Return true if the status indicates that a transaction can be started. This
     * would normally mean that no transaction is currently active.
     *
     * @param status The current transaction status
     * @return true if the current state allows for a transaction to be started
     */
    @Override
    protected boolean canBeginTransaction_impl(Object status) {
        return getIntStatus(status) == Status.STATUS_NO_TRANSACTION;
    }

    /**
     * INTERNAL:
     * Return true if the status indicates that a transaction can be committed. This
     * would normally mean that a transaction is currently active.
     *
     * @param status The current transaction status
     * @return true if the current state allows for a transaction to be committed
     */
    @Override
    protected boolean canCommitTransaction_impl(Object status) {
        return getIntStatus(status) == Status.STATUS_ACTIVE;
    }

    /**
     * INTERNAL:
     * Return true if the status indicates that a transaction can be rolled back. This
     * would normally mean that a transaction is currently active.
     *
     * @param status The current transaction status
     * @return true if the current state allows for a transaction to be rolled back
     */
    @Override
    protected boolean canRollbackTransaction_impl(Object status) {
        return getIntStatus(status) == Status.STATUS_ACTIVE;
    }

    /**
     * INTERNAL:
     * Return true if the status indicates that the SQL should be issued to the db.
     * This would normally mean that a transaction was active.
     *
     * @param status The current transaction status
     * @return true if the current state allows for the SQL to be sent to the database
     */
    @Override
    protected boolean canIssueSQLToDatabase_impl(Object status) {
        int stat = getIntStatus(status);
        return ((stat == Status.STATUS_ACTIVE) || (stat == Status.STATUS_PREPARING));
    }

    /**
     * INTERNAL:
     * Return true if the status indicates that the unit of work should be merged
     * into the shared cache. This would normally mean that the transaction was
     * committed successfully.
     *
     * @param status The current transaction status
     * @return true if the current state dictates that the unit of work should be merged
     */
    @Override
    protected boolean canMergeUnitOfWork_impl(Object status) {
        return getIntStatus(status) == Status.STATUS_COMMITTED;
    }

    /**
     * INTERNAL:
     * Return true if the transaction is rolled back.
     */
    @Override
    public boolean isRolledBack_impl(Object status) {
        return getIntStatus(status) == Status.STATUS_ROLLEDBACK;
    }

    /**
     * INTERNAL:
     * Obtain and return the JTA TransactionManager on this platform.
     * By default try java:comp JNDI lookup.
     *
     * This method can be can be overridden by subclasses to obtain the
     * transaction manager by whatever means is appropriate to the server.
     * This method is invoked by the constructor to initialize the transaction
     * manager at instance-creation time. Alternatively the transaction manager
     * can be set directly on the controller instance using the
     * setTransactionManager() method after the instance has been created.
     *
     * @return The TransactionManager for the transaction system
     */
    protected TransactionManager acquireTransactionManager() throws Exception {
        if (defaultTransactionManager != null) {
            return defaultTransactionManager;
        }
        return null;
    }

    /**
     * INTERNAL:
     * Convenience method to return the int value of the transaction status.
     * Assumes that the status object is an Integer.
     */
    protected int getIntStatus(Object status) {
        return (Integer) status;
    }

    /**
     * PUBLIC:
     * Return the transaction manager used to control the JTA transactions.
     *
     * @return The JTA TransactionManager that is used to obtain transaction
     * state information and control the active transaction.
     */
    public TransactionManager getTransactionManager() {
        return transactionManager;
    }

    /**
     * PUBLIC:
     * Set the transaction manager used to control the JTA transactions.
     *
     * @param mgr A valid JTA TransactionManager that can be
     * accessed by this controller to obtain transaction state information and
     * control the active transaction.
     */
    public void setTransactionManager(TransactionManager mgr) {
        transactionManager = mgr;
    }

    /**
     * INTERNAL:
     * Convert the status to a string for tracing.
     */
    static String[] codes = { "STATUS_ACTIVE", "MARKED_ROLLBACK", "PREPARED", "COMMITTED", "ROLLEDBACK", "UNKNOWN", "NO_TRANSACTION", "PREPARING", "COMMITTING", "ROLLING_BACK" };

    @Override
    protected String statusToString_impl(Object status) {
        int statusCode = getIntStatus(status);
        return codes[statusCode];
    }

    public static TransactionManager getDefaultTransactionManager() {
        return defaultTransactionManager;
    }

    /**
     * PUBLIC:
     * Set the JTA transaction manager to be used.
     * This can be called directly before login to configure JTA integration manually, or using Spring injection.
     */
    public static void setDefaultTransactionManager(TransactionManager defaultTransactionManager) {
        JTATransactionController.defaultTransactionManager = defaultTransactionManager;
    }
}
