/*
 * 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.openjpa.kernel;

import javax.transaction.NotSupportedException;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.transaction.xa.XAResource;

import org.apache.openjpa.ee.AbstractManagedRuntime;
import org.apache.openjpa.ee.ManagedRuntime;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.util.InternalException;
import org.apache.openjpa.util.InvalidStateException;
import org.apache.openjpa.util.StoreException;
import org.apache.openjpa.util.UserException;

/**
 * Uses a local implementation of the {@link TransactionManager} interface.
 * This manager is valid only for a single {@link Broker}.
 * It duplicates non-managed transaction control.
 *
 * @author Abe White
 */
class LocalManagedRuntime extends AbstractManagedRuntime
    implements ManagedRuntime, TransactionManager, Transaction {

    private static final Localizer _loc = Localizer.forPackage
        (LocalManagedRuntime.class);

    private Synchronization _broker = null;
    private Synchronization _factorySync = null;
    private boolean _active = false;
    private Throwable _rollbackOnly = null;

    /**
     * Constructor. Provide broker that will be requesting managed
     * transaction info.
     */
    public LocalManagedRuntime(Broker broker) {
        _broker = broker;
    }

    @Override
    public TransactionManager getTransactionManager() {
        return this;
    }

    @Override
    public synchronized void begin() {
        if (_active)
            throw new InvalidStateException(_loc.get("active"));
        _active = true;
    }

    @Override
    public synchronized void commit() {
        if (!_active)
            throw new InvalidStateException(_loc.get("not-active"));

        // try to invoke before completion in preparation for commit
        RuntimeException err = null;
        if (_rollbackOnly == null) {
            try {
                _broker.beforeCompletion();
                if (_factorySync != null)
                    _factorySync.beforeCompletion();
            } catch (RuntimeException re) {
                _rollbackOnly = re;
                err = re;
            }
        } else // previously marked rollback only
            err = new StoreException(_loc.get("marked-rollback")).
                setCause(_rollbackOnly).setFatal(true);

        if (_rollbackOnly == null) {
            try {
                _broker.afterCompletion(Status.STATUS_COMMITTED);
                notifyAfterCompletion(Status.STATUS_COMMITTED);
            } catch (RuntimeException re) {
                if (err == null)
                    err = re;
            }
        }

        // if we haven't managed to commit, rollback
        if (_active) {
            try {
                rollback();
            } catch (RuntimeException re) {
                if (err == null)
                    err = re;
            }
        }

        // throw the first exception we encountered, if any
        if (err != null)
            throw err;
    }

    @Override
    public synchronized void rollback() {
        if (!_active)
            throw new InvalidStateException(_loc.get("not-active"));

        // rollback broker
        RuntimeException err = null;
        try {
            _broker.afterCompletion(Status.STATUS_ROLLEDBACK);
        } catch (RuntimeException re) {
            err = re;
        }

        // rollback synch, even if broker throws exception
        try {
            notifyAfterCompletion(Status.STATUS_ROLLEDBACK);
        } catch (RuntimeException re) {
            if (err == null)
                err = re;
        }

        if (err != null)
            throw err;
    }

    /**
     * Notifies the factory sync that the transaction has ended with
     * the given status. Clears all transaction state regardless
     * of any exceptions during the callback.
     */
    private void notifyAfterCompletion(int status) {
        _active = false;

        try {
            if (_factorySync != null)
                _factorySync.afterCompletion(status);
        } finally {
            _rollbackOnly = null;
            _factorySync = null;
        }
    }

    @Override
    public synchronized void setRollbackOnly() {
        setRollbackOnly(new UserException());
    }

    @Override
    public void setRollbackOnly(Throwable cause) {
        _rollbackOnly = cause;
    }

    @Override
    public Throwable getRollbackCause() {
        return _rollbackOnly;
    }

    @Override
    public synchronized int getStatus() {
        if (_rollbackOnly != null)
            return Status.STATUS_MARKED_ROLLBACK;
        if (_active)
            return Status.STATUS_ACTIVE;
        return Status.STATUS_NO_TRANSACTION;
    }

    @Override
    public Transaction getTransaction() {
        return this;
    }

    @Override
    public void resume(Transaction tobj)
        throws SystemException {
        throw new SystemException(NotSupportedException.class.getName());
    }

    @Override
    public void setTransactionTimeout(int sec)
        throws SystemException {
        throw new SystemException(NotSupportedException.class.getName());
    }

    @Override
    public Transaction suspend()
        throws SystemException {
        throw new SystemException(NotSupportedException.class.getName());
    }

    @Override
    public boolean delistResource(XAResource xaRes, int flag)
        throws SystemException {
        throw new SystemException(NotSupportedException.class.getName());
    }

    @Override
    public boolean enlistResource(XAResource xaRes)
        throws SystemException {
        throw new SystemException(NotSupportedException.class.getName());
    }

    @Override
    public synchronized void registerSynchronization(Synchronization sync) {
        if (sync == _broker)
            return;
        if (_factorySync != null)
            throw new InternalException();
        _factorySync = sync;
    }
}

