/*
 * 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.felix.transaction.internal;

import java.util.Map;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import javax.transaction.Transaction;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.xa.XAException;

import org.apache.geronimo.transaction.manager.GeronimoTransactionManager;
import org.apache.geronimo.transaction.manager.TransactionLog;
import org.apache.geronimo.transaction.manager.XidFactory;
import org.apache.geronimo.transaction.manager.TransactionManagerMonitor;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.jta.JtaTransactionManager;

/**
 */
public class GeronimoPlatformTransactionManager extends GeronimoTransactionManager implements PlatformTransactionManager {

    private final PlatformTransactionManager platformTransactionManager;
    private final Map<Transaction, SuspendedResourcesHolder> suspendedResources = new ConcurrentHashMap<Transaction, SuspendedResourcesHolder>();

    public GeronimoPlatformTransactionManager() throws XAException {
        platformTransactionManager = new JtaTransactionManager(this, this);
        registerTransactionAssociationListener();
    }

    public GeronimoPlatformTransactionManager(int defaultTransactionTimeoutSeconds) throws XAException {
        super(defaultTransactionTimeoutSeconds);
        platformTransactionManager = new JtaTransactionManager(this, this);
        registerTransactionAssociationListener();
    }

    public GeronimoPlatformTransactionManager(int defaultTransactionTimeoutSeconds, TransactionLog transactionLog) throws XAException {
        super(defaultTransactionTimeoutSeconds, transactionLog);
        platformTransactionManager = new JtaTransactionManager(this, this);
        registerTransactionAssociationListener();
    }

    public GeronimoPlatformTransactionManager(int defaultTransactionTimeoutSeconds, XidFactory xidFactory, TransactionLog transactionLog) throws XAException {
        super(defaultTransactionTimeoutSeconds, xidFactory, transactionLog);
        platformTransactionManager = new JtaTransactionManager(this, this);
        registerTransactionAssociationListener();
    }

    public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
        return platformTransactionManager.getTransaction(definition);
    }

    public void commit(TransactionStatus status) throws TransactionException {
        platformTransactionManager.commit(status);
    }

    public void rollback(TransactionStatus status) throws TransactionException {
        platformTransactionManager.rollback(status);
    }

    protected void registerTransactionAssociationListener() {
        addTransactionAssociationListener(new TransactionManagerMonitor() {
            public void threadAssociated(Transaction transaction) {
                try {
                    if (transaction.getStatus() == Status.STATUS_ACTIVE) {
                        SuspendedResourcesHolder holder = suspendedResources.remove(transaction);
                        if (holder != null && holder.getSuspendedSynchronizations() != null) {
                            TransactionSynchronizationManager.setActualTransactionActive(true);
                            TransactionSynchronizationManager.setCurrentTransactionReadOnly(holder.isReadOnly());
                            TransactionSynchronizationManager.setCurrentTransactionName(holder.getName());
                            TransactionSynchronizationManager.initSynchronization();
                            for (Iterator<?> it = holder.getSuspendedSynchronizations().iterator(); it.hasNext();) {
                                TransactionSynchronization synchronization = (TransactionSynchronization) it.next();
                                synchronization.resume();
                                TransactionSynchronizationManager.registerSynchronization(synchronization);
                            }
                        }
                    }
                } catch (SystemException e) {
                    return;
                }
            }
            public void threadUnassociated(Transaction transaction) {
                try {
                    if (transaction.getStatus() == Status.STATUS_ACTIVE) {
                        if (TransactionSynchronizationManager.isSynchronizationActive()) {
                            List<?> suspendedSynchronizations = TransactionSynchronizationManager.getSynchronizations();
                            for (Iterator<?> it = suspendedSynchronizations.iterator(); it.hasNext();) {
                                ((TransactionSynchronization) it.next()).suspend();
                            }
                            TransactionSynchronizationManager.clearSynchronization();
                            String name = TransactionSynchronizationManager.getCurrentTransactionName();
                            TransactionSynchronizationManager.setCurrentTransactionName(null);
                            boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
                            TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);
                            TransactionSynchronizationManager.setActualTransactionActive(false);
                            SuspendedResourcesHolder holder = new SuspendedResourcesHolder(null, suspendedSynchronizations, name, readOnly);
                            suspendedResources.put(transaction, holder);
                        }
                    }
                } catch (SystemException e) {
                    return;
                }
            }
        });
    }

    /**
     * Holder for suspended resources.
     * Used internally by <code>suspend</code> and <code>resume</code>.
     */
    private static class SuspendedResourcesHolder {

        private final Object suspendedResources;

        private final List<?> suspendedSynchronizations;

        private final String name;

        private final boolean readOnly;

        public SuspendedResourcesHolder(
                Object suspendedResources, List<?> suspendedSynchronizations, String name, boolean readOnly) {

            this.suspendedResources = suspendedResources;
            this.suspendedSynchronizations = suspendedSynchronizations;
            this.name = name;
            this.readOnly = readOnly;
        }

        public Object getSuspendedResources() {
            return suspendedResources;
        }

        public List<?> getSuspendedSynchronizations() {
            return suspendedSynchronizations;
        }

        public String getName() {
            return name;
        }

        public boolean isReadOnly() {
            return readOnly;
        }
    }

}
