/*
 * 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:
//     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 Integer.valueOf(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).intValue();
    }

    /**
     * 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;
    }
}
