package com.sikey.wa04.business.infrastructure.aop;

import cn.hutool.core.lang.UUID;
import com.sikey.wa04.common.constants.HeaderConstant;
import com.sikey.wa04.common.constants.TraceConstant;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.jboss.logging.MDC;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

/**
 * 消息处理器跟踪
 *
 * @author luoyangwei
 */
@Slf4j
@Aspect
@Component
public class TracerAspect {
    @Pointcut("@annotation(com.sikey.wa04.business.infrastructure.aop.Tracer)")
    public void pointcut() {
    }

    @Before("pointcut()")
    public void beforeAdvice() {
    }

    @After("pointcut()")
    public void afterAdvice() {
        MDC.remove(TraceConstant.REQUEST_ID);
    }

    @Around("pointcut()")
    public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
        List<Object> args = Arrays.stream(pjp.getArgs()).toList();
        for (Object arg : args) {
            if (arg instanceof MessageHeaders messageHeaders) {
                log.info("Messaging handler trace, args: {}", args);
                MDC.put(TraceConstant.REQUEST_ID, messageHeaders.get(HeaderConstant.REQUEST_ID));
                return pjp.proceed();
            }
        }

        MDC.put(TraceConstant.REQUEST_ID, UUID.randomUUID().toString());
        return pjp.proceed();
    }

}
