package com.czg.utils;

import cn.hutool.core.lang.func.Func0;
import cn.hutool.core.thread.ThreadUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.NestedExceptionUtils;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

/**
 * @author zs
 */
@Slf4j
public class FunUtils {
    /**
     * 执行方法并捕获异常
     *
     * @param func  方法
     * @param value 失败的值
     */
    public static <T> T safeRun(Func0<T> func, T value) {
        try {
            return func.call();
        } catch (Exception e) {
            log.warn("方法执行失败: {}", e.getMessage());
        }

        return value;
    }

    public static void asyncSafeRunVoid(Runnable func, String... msg) {
        ThreadUtil.execAsync(() -> safeRunVoid(func, msg));
    }


    public static void safeRunVoid(Runnable func, String... msg) {
        try {
            func.run();
        } catch (Exception e) {
            String message = NestedExceptionUtils.getMostSpecificCause(e).getMessage();
            log.warn((msg.length > 0 ? msg[0] : "方法执行失败") + ": " + message);
        }
    }

    public static void safeRunVoid(Runnable func, String errorMsg, Object... args) {
        try {
            func.run();
        } catch (Exception e) {
            log.error(errorMsg, args, e);
        }
    }

    /**
     * 在事务提交后执行方法
     *
     * @param func 方法
     */
    public static void transactionSafeRun(Runnable func) {
        try {
            if (TransactionSynchronizationManager.isSynchronizationActive()) {
                TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
                    @Override
                    public void afterCommit() {
                        safeRunVoid(func, "");
                    }
                });
            } else {
                safeRunVoid(func, "");
            }
        } catch (Exception e) {
            log.error("方法执行失败: {}", e.getMessage());
        }
    }
}
