package com.czg.aspect;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.czg.utils.ServletUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
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.slf4j.MDC;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.util.Map;


/**
 * 方法调用统一切面处理
 *
 * @author ww
 */
@Aspect
@Component
@Slf4j
@Profile({"test", "dev", "prod"})
//@Profile({"test"})
public class ControllerAspect {

    @Pointcut("execution(public * (com.czg.controller..*).*(..)))")
    public void pkg() {
    }

    @Around("pkg()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.currentTimeMillis();
        //避免回填
        Object[] args = pjp.getArgs();

        // 如果请求参数中包含HttpServletRequest，剔除HttpServletRequest
        for (int i = 0; i < args.length; i++) {
            if (args[i] instanceof HttpServletRequest || args[i] instanceof HttpServletResponse) {
                args[i] = null;
            } else if (args[i] instanceof MultipartFile) {
                args[i] = "上传图片";
            }
        }

        String params = JSONObject.toJSONString(args);
        if(params.contains("jndi:rmi:")){
            throw new RuntimeException("gun");
        }
        Map<String, String> contextMap = MDC.getCopyOfContextMap();
        // 执行被拦截的方法
        Object result = pjp.proceed();
        long end = System.currentTimeMillis();
        HttpServletRequest request = ServletUtil.getRequest();
        String method = request.getMethod();
        String requestUrl = request.getRequestURL().toString();
        String requestIp = ServletUtil.getClientIP(request);
        long useTime = end - start;

        ThreadUtil.execAsync(() -> {
            if (contextMap != null) {
                MDC.setContextMap(contextMap);
            }

            //请求的参数
            String resultJson = JSONObject.toJSONString(result);
            if (StrUtil.isNotBlank(resultJson) && resultJson.length() > 200) {
                resultJson = resultJson.substring(0, 200);
            }
            try {
                if (StrUtil.isNotBlank(resultJson) && !"null".equals(resultJson)) {
                    log.info("""

                                           >>>>>> {} {}
                                           >>>>>> IP: {}
                                           >>>>>> execute time:{}ms
                                           >>>>>> Request: {}
                                           >>>>>> Response: {}
                                    """,
                            method, requestUrl, requestIp, useTime,
                            params,
                            resultJson
                    );
                }
            } catch (Exception e) {
                log.error("Request 为空" + e.getMessage());
            } finally {
                MDC.clear();
            }
        });
        return result;
    }
}
