/*
 * 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
//     07/13/2012-2.5 Guy Pelletier
//       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
//     08/24/2012-2.5 Guy Pelletier
//       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
//     09/13/2013-2.5 Guy Pelletier
//       - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
package org.eclipse.persistence.internal.jpa.transaction;

import java.util.Map;
import java.util.WeakHashMap;

import jakarta.persistence.RollbackException;

import org.eclipse.persistence.exceptions.TransactionException;
import org.eclipse.persistence.internal.jpa.QueryImpl;
import org.eclipse.persistence.internal.jpa.transaction.EntityTransactionWrapper;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;

/**
 * JDK 1.5 version of the EntityTransaction.  Differs from base version only in that
 * it takes a JDK 1.5 version of the EntityTransactionWrapper.
 *
 * @see org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl
 */
public class EntityTransactionImpl implements jakarta.persistence.EntityTransaction {
    /**
     * Keep a weak reference to the open queries that are executed in this entity manager.
     */
    protected WeakHashMap<QueryImpl, QueryImpl> openQueriesMap;

    protected EntityTransactionWrapper wrapper;

    protected boolean active = false;

    protected boolean rollbackOnly = false;

    protected TransactionFinalizer finalizer;

    /** PERF: Avoid finalization if not required by the application, and finalizers have major concurrency affects. */
    public static boolean isFinalizedRequired = false;

    public EntityTransactionImpl(EntityTransactionWrapper wrapper) {
        this.wrapper = wrapper;
        if (isFinalizedRequired) {
            this.finalizer = new TransactionFinalizer();
        }
    }

    /**
     * Within a transaction track any open queries that will need to be closed
     * on commit or rollback.
     */
    /**
     * Queries that leave the connection and are executed against this entity
     * manager will be added here. On rollback or commit any left over open
     * queries should be closed.
     *
     */
    public void addOpenQuery(QueryImpl query) {
        if (openQueriesMap == null) {
            openQueriesMap = new WeakHashMap<QueryImpl, QueryImpl>();
        }

        openQueriesMap.put(query, query);
    }

    /**
     * Start the current transaction. This can only be invoked if
     * {@link #isActive()} returns <code>false</code>.
     *
     * @throws IllegalStateException
     *             if isActive() is true.
     */
    @Override
    public void begin() {
        if (isActive()) {
            throw new IllegalStateException(TransactionException.transactionIsActive().getMessage());
        }
        //bug307445 : Throw IllegalStateException if entityManager was closed
        this.wrapper.getEntityManager().verifyOpen();

        // always extended
        this.wrapper.localUOW = this.wrapper.getEntityManager().getActivePersistenceContext(null);
        this.wrapper.localUOW.setShouldTerminateTransaction(false);

        this.active = true;
    }

    /**
     * Open queries within a transaction will be closed on commit or rollback
     * if they haven't already been closed.
     */
    protected void closeOpenQueries() {
        if (openQueriesMap != null) {
            for (QueryImpl openQuery : openQueriesMap.keySet()) {
                openQuery.close();
            }
        }
    }

    /**
     * Commit the current transaction, writing any un-flushed changes to the
     * database. This can only be invoked if {@link #isActive()} returns
     * <code>true</code>.
     *
     * @throws IllegalStateException
     *             if isActive() is false.
     */
    @Override
    public void commit() {
        if (!isActive()) {
            throw new IllegalStateException(TransactionException.transactionNotActive().getMessage());
        }

        // Make sure any open queries are closed.
        closeOpenQueries();

        try {
            if (this.wrapper.localUOW != null) {
                this.wrapper.localUOW.setShouldTerminateTransaction(true);
                if (!this.rollbackOnly) {
                    if (this.wrapper.localUOW.shouldResumeUnitOfWorkOnTransactionCompletion()) {
                        this.wrapper.localUOW.commitAndResume();
                        return;
                    } else {
                        this.wrapper.localUOW.commit();
                        // all change sets and are cleared, but the cache is
                        // kept
                        this.wrapper.localUOW.clearForClose(false);
                    }
                } else {
                    throw new RollbackException(ExceptionLocalization.buildMessage("rollback_because_of_rollback_only"));
                }
            }
        } catch (RuntimeException exception) {
            try {
                if (this.wrapper.localUOW != null) {
                    this.wrapper.getEntityManager().removeExtendedPersistenceContext();
                    this.wrapper.localUOW.release();
                    this.wrapper.localUOW.getParent().release();
                }
            } catch (Exception ignore) {} // Throw first exception.
            if (exception instanceof RollbackException) {
                throw exception;
            } else if (exception instanceof org.eclipse.persistence.exceptions.OptimisticLockException) {
                throw new RollbackException(new jakarta.persistence.OptimisticLockException(exception));
            } else {
                throw new RollbackException(exception);
            }
        } finally {
            this.active = false;
            this.rollbackOnly = false;
            this.wrapper.setLocalUnitOfWork(null);
        }
    }

    /**
     * Roll back the current transaction, discarding any changes that have
     * happened in this transaction. This can only be invoked if
     * {@link #isActive()} returns <code>true</code>.
     *
     * @throws IllegalStateException
     *             if isActive() is false.
     */
    @Override
    public void rollback() {
        if (!isActive()) {
            throw new IllegalStateException(TransactionException.transactionNotActive().getMessage());
        }

        // Make sure any open queries are closed.
        closeOpenQueries();

        try {
            if (wrapper.getLocalUnitOfWork() != null) {
                this.wrapper.localUOW.setShouldTerminateTransaction(true);
                this.wrapper.localUOW.release();
                this.wrapper.localUOW.getParent().release();
            }
        } finally {
            this.active = false;
            this.rollbackOnly = false;
            this.wrapper.getEntityManager().removeExtendedPersistenceContext();
            this.wrapper.setLocalUnitOfWork(null);
        }
    }

    /**
     * Mark the current transaction so that the only possible outcome of the
     * transaction is for the transaction to be rolled back.
     *
     * @throws IllegalStateException
     *             if isActive() is false.
     */
    @Override
    public void setRollbackOnly() {
        if (!isActive()) {
            throw new IllegalStateException(TransactionException.transactionNotActive().getMessage());
        }

        this.rollbackOnly = true;
    }

    /**
     * Return the weak reference to the open queries.
     */
    protected Map<QueryImpl, QueryImpl> getOpenQueriesMap() {
        if (openQueriesMap == null) {
            openQueriesMap = new WeakHashMap<QueryImpl, QueryImpl>();
        }

        return openQueriesMap;
    }

    /**
     * Determine whether the current transaction has been marked for rollback.
     *
     * @throws IllegalStateException
     *             if isActive() is false.
     */
    @Override
    public boolean getRollbackOnly() {
        if (!isActive()) {
            throw new IllegalStateException(TransactionException.transactionNotActive().getMessage());
        }
        return this.rollbackOnly;
    }

    /**
     * Check to see if the current transaction is in progress.
     */
    @Override
    public boolean isActive() {
        return this.active;
    }

    class TransactionFinalizer {

        /**
         * Here incase a user does not commit or rollback an enityTransaction
         * but just throws it away. If we do not rollback the txn the connection
         * will go back into the pool.
         */
        @Override
        protected void finalize() throws Throwable {
            if (isActive()) {
                rollback();
            }
        }

    }
}
