package com.lesingle.creation.common.aspect;

import com.lesingle.creation.common.util.TraceIdUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

/**
 * TraceId 日志链路追踪切面
 * <p>
 * 在 Controller 层拦截请求，生成 TraceId 并放入 MDC，实现全链路日志追踪
 *
 * @author lesingle
 * @since 1.0.0
 */
@Slf4j
@Aspect
@Component
public class TraceIdAspect {

    /**
     * 环绕通知，拦截 Controller 层所有方法
     */
    @Around("execution(* com.lesingle.creation.controller..*.*(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();

        try {
            // 生成 TraceId 并放入 MDC
            TraceIdUtil.setTraceId();

            log.debug("请求开始，TraceId: {}", TraceIdUtil.getTraceId());

            // 执行目标方法
            Object result = joinPoint.proceed();

            long costTime = System.currentTimeMillis() - startTime;
            log.debug("请求结束，TraceId: {}, 耗时：{}ms", TraceIdUtil.getTraceId(), costTime);

            return result;
        } finally {
            // 清除 MDC，防止内存泄漏
            TraceIdUtil.clear();
        }
    }
}
