package com.lesingle.edu.common.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.MDC;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;
import java.util.UUID;

/**
 * TraceId 切面
 * 在 Controller 执行前生成 traceId 并放入 MDC，便于日志链路追踪
 */
@Slf4j
@Aspect
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class TraceIdAspect {

    /**
     * MDC 中 traceId 的 key
     */
    private static final String TRACE_ID_KEY = "traceId";

    /**
     * 切点：Controller 层所有方法
     */
    @Around("execution(* com.lesingle.edu.controller..*.*(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 生成 traceId（使用 UUID，前 8 位大写）
        String traceId = generateTraceId();

        // 放入 MDC 上下文
        MDC.put(TRACE_ID_KEY, traceId);

        try {
            // 执行目标方法
            return joinPoint.proceed();
        } finally {
            // 清理 MDC，防止内存泄漏
            MDC.clear();
        }
    }

    /**
     * 生成 traceId
     * 使用 UUID 的前 8 位，保证唯一性的同时保持简洁
     */
    private String generateTraceId() {
        return UUID.randomUUID().toString().replace("-", "").substring(0, 8).toUpperCase();
    }
}
