package cn.axzo.workflow.starter.mq.check;

import cn.axzo.workflow.common.model.response.mq.ProcessInstanceDTO;
import cn.axzo.workflow.starter.handler.ProcessInstanceEventHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * Starter MQ 监听实现检查
 *
 * @author wangli
 * @since 2025-08-25 20:06
 */
@Slf4j
public class ImplementationReadyChecker implements ApplicationListener<ApplicationReadyEvent> {

    private static final Class<ProcessInstanceEventHandler> TARGET_INTERFACE = ProcessInstanceEventHandler.class;
    // 要检查的方法列表，顺序对应二进制位的位置（从左到右）
    private static final List<String> METHOD_NAMES = Arrays.asList(
            "onCompleted",
            "onCancelled",
            "onRejected",
            "onAborted"
    );


    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        ApplicationContext context = event.getApplicationContext();
        // 获取所有实现了目标接口的Bean
        Map<String, ProcessInstanceEventHandler> handlers = context.getBeansOfType(TARGET_INTERFACE);
        if (handlers.isEmpty()) {
            log.warn("未找到实现 {} 接口的Bean, 请确保至少有一个实现类被正确扫描和注册。", TARGET_INTERFACE.getName());
        }

        // 记录每个方法是否被实现
        boolean[] methodImplemented = new boolean[4];
        Arrays.fill(methodImplemented, false);

        // 检查每个实现类
        for (ProcessInstanceEventHandler handler : handlers.values()) {
            Class<?> handlerClass = handler.getClass();

            // 检查每个方法是否被当前实现类覆盖
            for (int i = 0; i < METHOD_NAMES.size(); i++) {
                String methodName = METHOD_NAMES.get(i);
                try {
                    Method method = handlerClass.getMethod(methodName, ProcessInstanceDTO.class);
                    // 检查方法是否来自接口本身（如果是默认方法）还是实现类
                    if (method.getDeclaringClass() != ProcessInstanceEventHandler.class) {
                        methodImplemented[i] = true;
                    }
                } catch (NoSuchMethodException e) {
                    // 方法未被实现，保持默认值false
                }
            }
        }

        // 生成4位二进制数
        int binaryResult = 0;
        for (int i = 0; i < methodImplemented.length; i++) {
            if (methodImplemented[i]) {
                // 计算当前位对应的权重（第一位是8，第二位是4，以此类推）
                int weight = (int) Math.pow(2, 3 - i);
                binaryResult += weight;
            }
        }

        // 收集未实现的方法
        List<String> unimplementedMethods = new ArrayList<>();
        for (int i = 0; i < methodImplemented.length; i++) {
            if (!methodImplemented[i]) {
                unimplementedMethods.add(METHOD_NAMES.get(i));
            }
        }

        log.warn("实现 {} 接口的Bean数量: {}", TARGET_INTERFACE.getName(), handlers.size());
        log.warn("方法实现情况：(二进制:{})，(十进制:{})", String.format("%4s", Integer.toBinaryString(binaryResult)).replace(' ', '0'), binaryResult);
        if (!unimplementedMethods.isEmpty()) {
            log.error("以下方法未被任何实现类覆盖: {}。请确保至少有一个实现类覆盖这些方法以处理相应的事件。", String.join(", ", unimplementedMethods));
        } else {
            log.warn("Congratulations, passed the verification！");
            log.warn("祝贺，已通过必接事件的校验！但仍然请确保您的实现类逻辑正确无误，不允许出现空实现，否则生产问题自行负责！");
        }
    }
}
