package com.liquidnet.service.galaxy.aop;//package com.liquidnet.service.galaxy.aop;
//
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.serializer.SerializerFeature;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.liquidnet.commons.lang.util.CurrentUtil;
//import com.liquidnet.commons.lang.util.StringUtil;
//import com.liquidnet.service.galaxy.aop.annotation.ControllerLog;
//import lombok.extern.slf4j.Slf4j;
//import org.aspectj.lang.JoinPoint;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.*;
//import org.aspectj.lang.reflect.MethodSignature;
//import org.bouncycastle.asn1.ocsp.ResponseData;
//import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
//import org.springframework.stereotype.Component;
//import org.springframework.web.context.request.RequestAttributes;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.lang.reflect.Method;
//import java.util.Arrays;
//import java.util.HashMap;
//import java.util.Map;
//
///**
// * @author AnJiabin <anjiabin@zhengzai.tv>
// * @version V1.0
// * @Description: TODO
// * @class: GalaxyRequestLogAspect
// * @Package com.liquidnet.service.galaxy.aop
// * @Copyright: LightNet @ Copyright (c) 2021
// * @date 2022/3/11 12:46
// */
//@Component
//@Aspect
//@Slf4j
//public class GalaxyRequestLogAspect {
//
//    // 定义切点Pointcut
////    @Pointcut("@annotation(com.xxxx.aop.ICache)")
////    public void requestServer() {
////    }
//
//    /**
//     * 定义切点
//     */
//    @Pointcut("execution(* com.liquidnet.service.galaxy.controller..*(..))")
//    public void requestServer() {
//    }
//
//    @Around("requestServer()")
//    public Object doAround(ProceedingJoinPoint pjp) {
//        //记录请求开始执行时间：
//        long beginTime = System.currentTimeMillis();
//        //获取请求信息
//        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        HttpServletRequest request = sra.getRequest();
//
//        //获取代理地址、请求地址、请求类名、方法名
//        String remoteAddress = CurrentUtil.getCliIpAddr();
//        String requestURI = request.getRequestURI();
//        String methodName = pjp.getSignature().getName();
//        String clazzName = pjp.getTarget().getClass().getSimpleName();
//
//        //获取请求参数：
//        MethodSignature ms = (MethodSignature) pjp.getSignature();
//        //获取请求参数类型
//        String[] parameterNames = ms.getParameterNames();
//        //获取请求参数值
//        Object[] parameterValues = pjp.getArgs();
//        StringBuilder sb = new StringBuilder();
//        //组合请求参数，进行日志打印
//        if (parameterNames != null && parameterNames.length > 0) {
//            for (int i = 0; i < parameterNames.length; i++) {
//                if (parameterNames[i].equals("bindingResult")) {
//                    break;
//                }
//                if ((parameterValues[i] instanceof HttpServletRequest) || (parameterValues[i] instanceof HttpServletResponse)) {
//                    sb.
//                            append("[").
//                            append(parameterNames[i]).append("=").append(parameterValues[i])
//                            .append("]");
//                } else {
//                    sb.
//                            append("[").
//                            append(parameterNames[i]).append("=")
//                            .append(JSON.toJSONString(parameterValues[i], SerializerFeature.WriteDateUseDateFormat))
//                            .append("]");
//                }
//            }
//        }
//        Object result = null;
//        try {
//            result = pjp.proceed();
//        } catch (Throwable throwable) {
//            //请求操纵失败
//            //记录错误日志
//            log.error("切面处理请求错误！ IP信息：【{}】 " +
//                            "URI信息：【{}】 请求映射控制类：【{}】 " +
//                            "请求方法：【{}】 请求参数列表：【{}】", remoteAddress, requestURI, clazzName, methodName,
//                    sb.toString());
////            log.error("(ง•̀_•́)ง (っ•̀ω•́)っ          切面处理请求错误！ IP信息(ง•̀_•́)ง->： 【{}}】 " +
////                            "URI信息(ง•̀_•́)ง->：【{}】 请求映射控制类(ง•̀_•́)ง->：【{}】 " +
////                            "请求方法(ง•̀_•́)ง->：【{}】 请求参数列表(ง•̀_•́)ง->：【{}】", remoteAddress, requestURI, clazzName, methodName,
////                    sb.toString());
//        }
//        //请求操作成功
//        String resultJosnString = "";
//        if (result != null) {
//            if (result instanceof ResponseData) {
//                resultJosnString = JSON.toJSONString(result, SerializerFeature.WriteDateUseDateFormat);
//            } else {
//                resultJosnString = String.valueOf(result);
//            }
//        }
//        //记录请求完成执行时间：
//        long endTime = System.currentTimeMillis();
//        long usedTime = endTime - beginTime;
//        //记录日志
//        log.info("请求操作成功！ 请求耗时：【{}ms】 ", usedTime);
////        log.info("请求操作成功！ 请求耗时：【{}】 " +
////                        "IP信息(◍'౪`◍)ﾉﾞ->： 【{}}】  URI信息(◍'౪`◍)ﾉﾞ->：【{}】 " +
////                        "请求映射控制类(◍'౪`◍)ﾉﾞ->：【{}】 请求方法(◍'౪`◍)ﾉﾞ->：【{}】 " +
////                        "请求参数列表(◍'౪`◍)ﾉﾞ->：【{}】 返回值(◍'౪`◍)ﾉﾞ->：【{}】", usedTime, remoteAddress, requestURI, clazzName,
////                methodName, sb.toString(), resultJosnString);
//
//        return result;
//    }
//
//    @Before("requestServer()")
//    public void before(JoinPoint joinPoint){
//        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
//        HttpServletRequest request = servletRequestAttributes.getRequest();
//        //这一步获取到的方法有可能是代理方法也有可能是真实方法
//        Method m = ((MethodSignature) joinPoint.getSignature()).getMethod();
//        //判断代理对象本身是否是连接点所在的目标对象，不是的话就要通过反射重新获取真实方法
//        if (joinPoint.getThis().getClass() != joinPoint.getTarget().getClass()) {
//            m = this.getMethod(joinPoint.getTarget().getClass(), m.getName(), m.getParameterTypes());
//        }
//        //通过真实方法获取该方法的参数名称
//        LocalVariableTableParameterNameDiscoverer paramNames = new LocalVariableTableParameterNameDiscoverer();
//        String[] parameterNames = paramNames.getParameterNames(m);
//        //获取连接点方法运行时的入参列表
//        Object[] args = joinPoint.getArgs();
//        //将参数名称与入参值一一对应起来
//        Map<String, Object> params = new HashMap<>();
//        //自己写的一个判空类方法
//        if (!StringUtil.isEmpty(parameterNames)){
//            for (int i = 0; i < parameterNames.length; i++) {
//                //这里加一个判断，如果使用requestParam接受参数，加了require=false，这里会存现不存在的现象
//                if (StringUtil.isEmpty(args[i])){
//                    continue;
//                }
//                //通过所在类转换，获取值，包含各种封装类都可以
//                ObjectMapper objectMapper = new ObjectMapper();
//                objectMapper.convertValue(args[i],args[i].getClass());
//                params.put(parameterNames[i],JSON.toJSON(objectMapper.convertValue(args[i],args[i].getClass())));
//            }
//        }
//        log.info("----------【{}】before start:---------------------",getMethodDesc(m));
//        log.info("URL : " + request.getRequestURL().toString());
//        log.info("HTTP_METHOD : " + request.getMethod());
//        log.info("IP : " + request.getRemoteAddr());
//        log.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName()+ "." + joinPoint.getSignature().getName());
//        //这里经过处理，就可以获得参数名字与值一一对应
//        log.info("ARGS-JSON : " + params);
//        //这个就是纯粹拿到参数，值需要自己匹配
//        log.info("ARGS : "+ Arrays.toString(joinPoint.getArgs()));
//        log.info("----------【{}】before end:---------------------",getMethodDesc(m));
//
//    }
//
//    @AfterThrowing("requestServer()")
//    public void AfterThrowing(){
//        System.out.println("异常通知....");
//    }
//
////    @After("requestServer()")
////    public void after(JoinPoint point){
////        System.out.println("@After：模拟释放资源...");
////
////        log.info("before return+++++++++++++++++++++++++++");
////        log.info("@After：目标方法为：" +
////                point.getSignature().getDeclaringTypeName() +
////                "." + point.getSignature().getName());
////        log.info("@After：参数为：" + Arrays.toString(point.getArgs()));
////        System.out.println("@After：被织入的目标对象为：" + point.getTarget());
////        log.info("end return++++++++++++++++++++++++++++++++");
////    }
//
//    @AfterReturning(value = "requestServer()",returning = "rtv")
//    public void AfterReturning(JoinPoint joinPoint, Object rtv){
//        log.info("before return+++++++++++++++++++++++++++");
//        log.info("responseBody:"+ JSON.toJSONString(rtv, SerializerFeature.WriteMapNullValue));
//        log.info("end return++++++++++++++++++++++++++++++++");
//    }
//
//    private Method getMethod(Class<?> classt,String methodName,Class<?>[] parameterTypes){
//        Method rsMethod = null;
//        Method[] methods = classt.getMethods();
//        String description = "";
//        for (Method method : methods) {
//            if (method.getName().equals(methodName)) {
//                rsMethod =  method;
////                Class[] clazzs = method.getParameterTypes();
////                if (clazzs.length == parameterTypes.length) {
////                    description = method.getAnnotation(ControllerLog.class).description();
////                    break;
////                }
//            }
//        }
//        return rsMethod;
//    }
//
//    private String getMethodDesc(Method method){
//        String rsMethodDesc = "未知方法";
//        if(!StringUtil.isNull(method)){
//            rsMethodDesc = method.getAnnotation(ControllerLog.class).description();
//        }
//        return rsMethodDesc;
//    }
//
//}