package com.bcxin.tenant.domain.utils;

import com.bcxin.Infrastructures.UnitWork;
import com.bcxin.Infrastructures.components.RetryProvider;
import com.bcxin.Infrastructures.enums.ProcessedStatus;
import com.bcxin.tenant.domain.entities.EventSubscriberEntity;
import com.bcxin.tenant.domain.entities.TenantEventEntity;
import com.bcxin.tenant.domain.repositories.EventSubscribedActionLogRepository;
import com.bcxin.tenant.domain.repositories.EventSubscriberRepository;
import com.bcxin.tenant.domain.repositories.TenantEventRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

public class ExecuteUtils {
    private final static Logger logger = LoggerFactory.getLogger(ExecuteUtils.class);

    public static void executeTenantEventAction(
            TenantEventEntity eventEntity,
            EventSubscriberEntity subscriber,
            Runnable runnable,
            RetryProvider retryProvider,
            EventSubscribedActionLogRepository eventSubscribedActionLogRepository,
            EventSubscriberRepository eventSubscriberRepository,
            TenantEventRepository tenantEventRepository,
            UnitWork unitWork) {
        String message = "";
        try {
            /**
             * 重试多次
             */
            retryProvider.execute(runnable, 10);
        } catch (Exception ex) {
            message = ex.getMessage();
            logger.error(String.format("ExecuteUtils.executeTenantEventAction:%s", subscriber.getSelector()), ex);
        } finally {
            try {
                if (StringUtils.hasLength(message)) {
                    subscriber.error(eventSubscribedActionLogRepository, eventEntity, ProcessedStatus.Error, message);
                    eventEntity.error(message);
                } else {
                    subscriber.done(eventSubscribedActionLogRepository, eventEntity, ProcessedStatus.Done, "订阅执行成功");
                    eventEntity.done("事件消费成功");
                }

                retryProvider.execute(() -> {
                    unitWork.executeNewTran(() -> {
                        tenantEventRepository.save(eventEntity);

                        eventSubscriberRepository.save(subscriber);
                    });
                }, 10);
            } catch (Exception ex) {
                unitWork.detachAll();
                ex.printStackTrace();
            }
        }
    }
}
