package com.fs.framework.aspectj;

import com.fs.common.utils.TraceIdUtil;
import com.fs.newAdv.constant.ConversionTrackingMessage;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * RocketMQ消费者链路ID切面
 * 在消费消息前设置链路ID到MDC，保证整个消费链路的日志可追踪
 *
 * @author zhangqin
 */
@Aspect
@Component
@Slf4j
@Order(1) // 优先于 DistributeLockAspect 执行
public class RocketMQTraceIdAspect {

    @Pointcut("execution(* com.fs.app.mq.consumer.*.onMessage(..))")
    public void mqConsumerPointcut() {
    }

    @Around("mqConsumerPointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        String trackId = null;
        try {
            // 从消息参数中提取 trackId
            Object[] args = pjp.getArgs();
            if (args != null && args.length > 0) {
                Object message = args[0];
                if (message instanceof ConversionTrackingMessage) {
                    trackId = ((ConversionTrackingMessage) message).getTrackId();
                }
            }
            // 设置链路ID到MDC
            if (trackId != null && !trackId.isEmpty()) {
                TraceIdUtil.put(trackId);
            } else {
                // 如果没有 trackId，则生成一个新的
                TraceIdUtil.init();
            }
            return pjp.proceed();
        } finally {
            // 清理MDC，避免线程复用时链路ID污染
            TraceIdUtil.clear();
        }
    }
}
