package de.effigenix.infrastructure.config;

import de.effigenix.shared.common.Result;
import de.effigenix.shared.persistence.UnitOfWork;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.function.Supplier;

@Component
@Profile("!no-db")
public class SpringUnitOfWork implements UnitOfWork {

    private final PlatformTransactionManager txManager;

    public SpringUnitOfWork(PlatformTransactionManager txManager) {
        this.txManager = txManager;
    }

    @Override
    public <E, T> Result<E, T> executeAtomically(Supplier<Result<E, T>> work) {
        var txDef = new DefaultTransactionDefinition();
        var status = txManager.getTransaction(txDef);
        try {
            var result = work.get();
            if (result.isFailure()) {
                txManager.rollback(status);
            } else {
                txManager.commit(status);
            }
            return result;
        } catch (Exception e) {
            txManager.rollback(status);
            throw e;
        }
    }
}
