package com.nokia.domainb.config;

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.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * 日志切面
 */
@Aspect
@Component
@Slf4j
public class LogAspectConfig
{
    @Pointcut("execution(public * com.nokia..*Controller.*(..))")
    public void controllerPointcut()
    {
        // Pointcut
    }

    @Before("controllerPointcut()")
    public void doBefore(JoinPoint joinPoint)
    {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null)
        {
            return;
        }
        HttpServletRequest request = attributes.getRequest();
        log.info("请求地址: {} {}", request.getRequestURL().toString(), request.getMethod());
        Object[] args = joinPoint.getArgs();
        Object[] arguments = new Object[args.length];
        for (int i = 0; i < args.length; i++)
        {
            if (args[i] instanceof ServletRequest
                    || args[i] instanceof ServletResponse
                    || args[i] instanceof MultipartFile
                    || args[i] instanceof Exception
            )
            {
                continue;
            }
            arguments[i] = args[i];
        }
        log.info("入参: {}", JSON.toJSONString(arguments));
    }

    @Around("controllerPointcut()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable
    {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        Object result = proceedingJoinPoint.proceed();
        log.info("结果: {}", JSON.toJSONString(result));
        stopWatch.stop();
        log.info("耗时：{} ms", stopWatch.getTotalTimeMillis());
        return result;
    }
}