//package tech.easyflow.common.web.devlog;
//
//
//import com.alibaba.fastjson2.JSON;
//import com.alibaba.fastjson2.JSONWriter;
//import com.alibaba.fastjson2.filter.PropertyFilter;
//import com.mybatisflex.core.util.ClassUtil;
//import com.mybatisflex.core.util.StringUtil;
//import jakarta.servlet.http.HttpServletRequest;
//import org.apache.ibatis.javassist.*;
//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.aspectj.lang.reflect.MethodSignature;
//import org.springframework.context.annotation.Profile;
//import org.springframework.stereotype.Component;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//import org.springframework.web.servlet.ModelAndView;
//
//import java.lang.reflect.Method;
//import java.util.Enumeration;
//import java.util.StringJoiner;
//
//@Aspect
//@Component
//@Profile({"dev", "test"})
//public class DevLogAspect {
//
//    private static final int maxOutputLengthOfParaValue = 512;
//    private static ClassPool classPool = ClassPool.getDefault();
//
//    static {
//        classPool.appendClassPath(new LoaderClassPath(Thread.currentThread().getContextClassLoader()));
//    }
//
//
//    @Pointcut("within(@org.springframework.web.bind.annotation.RestController *) || execution(* tech.easyflow.common.web.controller.BaseCurdController.*(..))")
//    public void webLog() {
//    }
//
//    @Around("webLog()")
//    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
//        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        HttpServletRequest request = attributes.getRequest();
//
//        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
//        Class<?> controllerClass = signature.getDeclaringType();
//        Method method = signature.getMethod();
//
//        String url = request.getRequestURL().toString();
//        String param = getRequestParamsString(request);
//
//        int lineNumber = getLineNumber(controllerClass, method);
//
//
//        long startTime = System.currentTimeMillis();
//        Object result = null;
//        try {
//            result = proceedingJoinPoint.proceed();
//        } finally {
//            String logInfo = "\n" +
//                    "+========================================= Start ==========================================\n" +
//                    "| Request        : " + request.getMethod() + " " + url + "\n" +
//                    "| Request Params : " + param + "\n" +
//                    "| Request IP     : " + request.getRemoteAddr() + "\n" +
//                    "| Controller     : " + signature.getDeclaringTypeName() + "." + "(" + controllerClass.getSimpleName() + ".java:" + lineNumber + ")" + "\n" +
//                    "| Method         : " + method.getName() + buildParamsString(method) + "\n" +
//                    "| Response       : " + getResponseText(result) + "\n" +
//                    "| Elapsed Time   : " + (System.currentTimeMillis() - startTime) + " ms" + "\n" +
//                    "+========================================== End ===========================================\n";
//            System.out.println(logInfo);
//        }
//        return result;
//    }
//
//    private static String getResponseText(Object result) {
//        if (result instanceof ModelAndView && ((ModelAndView) result).isReference()) {
//            return ((ModelAndView) result).getViewName();
//        }
//
//        String originalText;
//        if (result instanceof String) {
//            originalText = (String) result;
//        } else {
//            originalText = JSON.toJSONString(result);
//        }
//
//        if (StringUtil.noText(originalText)) {
//            return "";
//        }
//
//        originalText = originalText.replace("\n", "");
//
//        if (originalText.length() > 100) {
//            return originalText.substring(0, 100) + "...";
//        }
//
//        try {
//            // 使用PropertyFilter过滤掉timeout字段
//            PropertyFilter filter = (object, name, value) -> !"timeout".equals(name);
//
//            String resultStr = JSON.toJSONString(result,
//                    filter,
//                    JSONWriter.Feature.WriteMapNullValue,
//                    JSONWriter.Feature.IgnoreNonFieldGetter);
//            return resultStr;
//        } catch (Exception e) {
//            return "[Serialization Error: " + e.getMessage() + "]";
//        }
//    }
//
//
//    private String buildParamsString(Method method) {
//        StringJoiner joiner = new StringJoiner(", ", "(", ")");
//        for (Class<?> parameterType : method.getParameterTypes()) {
//            joiner.add(parameterType.getSimpleName());
//        }
//        return joiner.toString();
//    }
//
//
//    private int getLineNumber(Class<?> controllerClass, Method method) throws NotFoundException {
//        CtClass ctClass = classPool.get(ClassUtil.getUsefulClass(controllerClass).getName());
//        classPool.get(ClassUtil.getUsefulClass(controllerClass).getName());
//        String desc = DevLogUtil.getMethodDescWithoutName(method);
//        CtMethod ctMethod = ctClass.getMethod(method.getName(), desc);
//        return ctMethod.getMethodInfo().getLineNumber(0);
//    }
//
//
//    private String getRequestParamsString(HttpServletRequest request) {
//        StringBuilder sb = new StringBuilder();
//        Enumeration<String> e = request.getParameterNames();
//        if (e.hasMoreElements()) {
//            while (e.hasMoreElements()) {
//                String name = e.nextElement();
//                String[] values = request.getParameterValues(name);
//                if (values.length == 1) {
//                    sb.append(name).append("=");
//                    if (values[0] != null && values[0].length() > maxOutputLengthOfParaValue) {
//                        sb.append(values[0], 0, maxOutputLengthOfParaValue).append("...");
//                    } else {
//                        sb.append(values[0]);
//                    }
//                } else {
//                    sb.append(name).append("[]={");
//                    for (int i = 0; i < values.length; i++) {
//                        if (i > 0) {
//                            sb.append(",");
//                        }
//                        sb.append(values[i]);
//                    }
//                    sb.append("}");
//                }
//                sb.append("  ");
//            }
//        }
//        return sb.toString();
//    }
//
//}
