package com.atlassian.stash.internal.spring;

import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.annotation.Nonnull;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * A default implementation of {@link TransactionSynchronizer} which uses the static API for
 * {@code TransactionSynchronizationManager} to register synchronizations.
 *
 * @since 2.9.5
 */
@Component("transactionSynchronizer")
public class DefaultTransactionSynchronizer implements TransactionSynchronizer {

    @Nonnull
    @Override
    public <K, V> TransactionalState<K, V> getTransactionState(@Nonnull Object namespace) {
        return new DefaultTransactionalState<>(checkNotNull(namespace, "namespace"));
    }

    @Override
    public boolean isAvailable() {
        return TransactionSynchronizationManager.isActualTransactionActive() &&
                TransactionSynchronizationManager.isSynchronizationActive(); //Should always be true in Stash, but...
    }

    @Override
    public boolean register(@Nonnull TransactionSynchronization synchronization) {
        if (isAvailable()) {
            TransactionSynchronizationManager.registerSynchronization(checkNotNull(synchronization, "synchronization"));

            return true;
        }

        return false;
    }
}
