package com.core.filter;

import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 切面日志
 */
@Slf4j
@Aspect
@Configuration
public class ControllerLoggerAspect {

    private static final Logger logger = LoggerFactory.getLogger(ControllerLoggerAspect.class);

    /** 以 controller 包下定义的所有请求为切入点 */
    @Pointcut("execution(public * yangtz.cs.*.controller..*.*(..))")
    public void requestLog() {}

    @Before("requestLog()")
    public void doBefore(JoinPoint joinPoint) {
        // 开始打印请求日志
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 打印请求相关参数
        log.info("============================= 开始打印 ==================================");
        // 打印请求 url
        log.info("请求URL  : {}", request.getRequestURL().toString());
        // 打印 Http method
        log.info("请求方式 HTTP Method   : {}", request.getMethod());
        // 打印调用 controller 的全路径以及执行方法
        log.info("调用方法 Class Method  : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
        // 打印请求的 IP
        log.info("请求IP         : {}", request.getRemoteAddr());
        // 打印请求入参
//        log.info("Request Args   : {}", new Gson.toJson(request.getParameterMap()));
        log.info("请求入参 Request Args   : {}", JSON.toJSON(request.getParameterMap()));
    }

    @Around("requestLog()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = proceedingJoinPoint.proceed();
        // 打印出参
//        log.info("Response Body  : {}", new Gson().toJson(result))
        log.info("响应出参 Response Body  : {}", JSON.toJSON(result));

        // 执行耗时
        log.info("执行耗时Time-Consuming : {} ms", System.currentTimeMillis() - startTime);
        return result;
    }

    @After("requestLog()")
    public void doAfter() {
        log.info("(u‿ฺu✿ฺ)");
        log.info("============================= 结束打印 ==================================");

    }
}
