/**
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.apache.commons.dbcp2.managed;

import org.apache.commons.dbcp2.ConnectionFactory;

import javax.transaction.TransactionManager;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Objects;

/**
 * An implementation of XAConnectionFactory which manages non-XA connections in XA transactions. A non-XA connection
 * commits and rolls back as part of the XA transaction, but is not recoverable since the connection does not implement
 * the 2-phase protocol.
 *
 * @since 2.0
 */
public class LocalXAConnectionFactory implements XAConnectionFactory {
    /**
     * LocalXAResource is a fake XAResource for non-XA connections. When a transaction is started the connection
     * auto-commit is turned off. When the connection is committed or rolled back, the commit or rollback method is
     * called on the connection and then the original auto-commit value is restored.
     * <p>
     * The LocalXAResource also respects the connection read-only setting. If the connection is read-only the commit
     * method will not be called, and the prepare method returns the XA_RDONLY.
     * </p>
     * It is assumed that the wrapper around a managed connection disables the setAutoCommit(), commit(), rollback() and
     * setReadOnly() methods while a transaction is in progress.
     *
     * @since 2.0
     */
    protected static class LocalXAResource implements XAResource {
        private final Connection connection;
        private Xid currentXid; // @GuardedBy("this")
        private boolean originalAutoCommit; // @GuardedBy("this")

        public LocalXAResource(final Connection localTransaction) {
            this.connection = localTransaction;
        }

        /**
         * Commits the transaction and restores the original auto commit setting.
         *
         * @param xid
         *            the id of the transaction branch for this connection
         * @param flag
         *            ignored
         * @throws XAException
         *             if connection.commit() throws an SQLException
         */
        @Override
        public synchronized void commit(final Xid xid, final boolean flag) throws XAException {
            Objects.requireNonNull(xid, "xid is null");
            if (this.currentXid == null) {
                throw new XAException("There is no current transaction");
            }
            if (!this.currentXid.equals(xid)) {
                throw new XAException("Invalid Xid: expected " + this.currentXid + ", but was " + xid);
            }

            try {
                // make sure the connection isn't already closed
                if (connection.isClosed()) {
                    throw new XAException("Connection is closed");
                }

                // A read only connection should not be committed
                if (!connection.isReadOnly()) {
                    connection.commit();
                }
            } catch (final SQLException e) {
                throw (XAException) new XAException().initCause(e);
            } finally {
                try {
                    connection.setAutoCommit(originalAutoCommit);
                } catch (final SQLException e) {
                    // ignore
                }
                this.currentXid = null;
            }
        }

        /**
         * This method does nothing.
         *
         * @param xid
         *            the id of the transaction branch for this connection
         * @param flag
         *            ignored
         * @throws XAException
         *             if the connection is already enlisted in another transaction
         */
        @Override
        public synchronized void end(final Xid xid, final int flag) throws XAException {
            Objects.requireNonNull(xid, "xid is null");
            if (!this.currentXid.equals(xid)) {
                throw new XAException("Invalid Xid: expected " + this.currentXid + ", but was " + xid);
            }

            // This notification tells us that the application server is done using this
            // connection for the time being. The connection is still associated with an
            // open transaction, so we must still wait for the commit or rollback method
        }

        /**
         * Clears the currently associated transaction if it is the specified xid.
         *
         * @param xid
         *            the id of the transaction to forget
         */
        @Override
        public synchronized void forget(final Xid xid) {
            if (xid != null && xid.equals(currentXid)) {
                currentXid = null;
            }
        }

        /**
         * Always returns 0 since we have no way to set a transaction timeout on a JDBC connection.
         *
         * @return always 0
         */
        @Override
        public int getTransactionTimeout() {
            return 0;
        }

        /**
         * Gets the current xid of the transaction branch associated with this XAResource.
         *
         * @return the current xid of the transaction branch associated with this XAResource.
         */
        public synchronized Xid getXid() {
            return currentXid;
        }

        /**
         * Returns true if the specified XAResource == this XAResource.
         *
         * @param xaResource
         *            the XAResource to test
         * @return true if the specified XAResource == this XAResource; false otherwise
         */
        @Override
        public boolean isSameRM(final XAResource xaResource) {
            return this == xaResource;
        }

        /**
         * This method does nothing since the LocalXAConnection does not support two-phase-commit. This method will
         * return XAResource.XA_RDONLY if the connection isReadOnly(). This assumes that the physical connection is
         * wrapped with a proxy that prevents an application from changing the read-only flag while enrolled in a
         * transaction.
         *
         * @param xid
         *            the id of the transaction branch for this connection
         * @return XAResource.XA_RDONLY if the connection.isReadOnly(); XAResource.XA_OK otherwise
         */
        @Override
        public synchronized int prepare(final Xid xid) {
            // if the connection is read-only, then the resource is read-only
            // NOTE: this assumes that the outer proxy throws an exception when application code
            // attempts to set this in a transaction
            try {
                if (connection.isReadOnly()) {
                    // update the auto commit flag
                    connection.setAutoCommit(originalAutoCommit);

                    // tell the transaction manager we are read only
                    return XAResource.XA_RDONLY;
                }
            } catch (final SQLException ignored) {
                // no big deal
            }

            // this is a local (one phase) only connection, so we can't prepare
            return XAResource.XA_OK;
        }

        /**
         * Always returns a zero length Xid array. The LocalXAConnectionFactory can not support recovery, so no xids
         * will ever be found.
         *
         * @param flag
         *            ignored since recovery is not supported
         * @return always a zero length Xid array.
         */
        @Override
        public Xid[] recover(final int flag) {
            return new Xid[0];
        }

        /**
         * Rolls back the transaction and restores the original auto commit setting.
         *
         * @param xid
         *            the id of the transaction branch for this connection
         * @throws XAException
         *             if connection.rollback() throws an SQLException
         */
        @Override
        public synchronized void rollback(final Xid xid) throws XAException {
            Objects.requireNonNull(xid, "xid is null");
            if (!this.currentXid.equals(xid)) {
                throw new XAException("Invalid Xid: expected " + this.currentXid + ", but was " + xid);
            }

            try {
                connection.rollback();
            } catch (final SQLException e) {
                throw (XAException) new XAException().initCause(e);
            } finally {
                try {
                    connection.setAutoCommit(originalAutoCommit);
                } catch (final SQLException e) {
                    // Ignore.
                }
                this.currentXid = null;
            }
        }

        /**
         * Always returns false since we have no way to set a transaction timeout on a JDBC connection.
         *
         * @param transactionTimeout
         *            ignored since we have no way to set a transaction timeout on a JDBC connection
         * @return always false
         */
        @Override
        public boolean setTransactionTimeout(final int transactionTimeout) {
            return false;
        }

        /**
         * Signals that a the connection has been enrolled in a transaction. This method saves off the current auto
         * commit flag, and then disables auto commit. The original auto commit setting is restored when the transaction
         * completes.
         *
         * @param xid
         *            the id of the transaction branch for this connection
         * @param flag
         *            either XAResource.TMNOFLAGS or XAResource.TMRESUME
         * @throws XAException
         *             if the connection is already enlisted in another transaction, or if auto-commit could not be
         *             disabled
         */
        @Override
        public synchronized void start(final Xid xid, final int flag) throws XAException {
            if (flag == XAResource.TMNOFLAGS) {
                // first time in this transaction

                // make sure we aren't already in another tx
                if (this.currentXid != null) {
                    throw new XAException("Already enlisted in another transaction with xid " + xid);
                }

                // save off the current auto commit flag so it can be restored after the transaction completes
                try {
                    originalAutoCommit = connection.getAutoCommit();
                } catch (final SQLException ignored) {
                    // no big deal, just assume it was off
                    originalAutoCommit = true;
                }

                // update the auto commit flag
                try {
                    connection.setAutoCommit(false);
                } catch (final SQLException e) {
                    throw (XAException) new XAException("Count not turn off auto commit for a XA transaction")
                            .initCause(e);
                }

                this.currentXid = xid;
            } else if (flag == XAResource.TMRESUME) {
                if (!xid.equals(this.currentXid)) {
                    throw new XAException("Attempting to resume in different transaction: expected " + this.currentXid
                            + ", but was " + xid);
                }
            } else {
                throw new XAException("Unknown start flag " + flag);
            }
        }
    }
    private final TransactionRegistry transactionRegistry;

    private final ConnectionFactory connectionFactory;

    /**
     * Creates an LocalXAConnectionFactory which uses the specified connection factory to create database connections.
     * The connections are enlisted into transactions using the specified transaction manager.
     *
     * @param transactionManager
     *            the transaction manager in which connections will be enlisted
     * @param connectionFactory
     *            the connection factory from which connections will be retrieved
     */
    public LocalXAConnectionFactory(final TransactionManager transactionManager,
            final ConnectionFactory connectionFactory) {
        Objects.requireNonNull(transactionManager, "transactionManager is null");
        Objects.requireNonNull(connectionFactory, "connectionFactory is null");
        this.transactionRegistry = new TransactionRegistry(transactionManager);
        this.connectionFactory = connectionFactory;
    }

    @Override
    public Connection createConnection() throws SQLException {
        // create a new connection
        final Connection connection = connectionFactory.createConnection();

        // create a XAResource to manage the connection during XA transactions
        final XAResource xaResource = new LocalXAResource(connection);

        // register the xa resource for the connection
        transactionRegistry.registerConnection(connection, xaResource);

        return connection;
    }

    /**
     * @return The connection factory.
     * @since 2.6.0
     */
    public ConnectionFactory getConnectionFactory() {
        return connectionFactory;
    }

    @Override
    public TransactionRegistry getTransactionRegistry() {
        return transactionRegistry;
    }

}
