package cn.component.logger;

import org.apache.commons.text.StringEscapeUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import cn.config.SysConfig;
import cn.util.core.IsKit;
import cn.util.core.LogKit;
import cn.util.core.ServletKit;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.filter.PropertyPreFilter;
import com.alibaba.fastjson2.filter.SimplePropertyPreFilter;
/**
 * 定义一个切点
 * see:注解
 */
@Aspect
@Component
public class RequestUrlAspect
{
	@Autowired
	private SysConfig env;
	 //定义一个切点api
    @Pointcut("execution(* cn.web.api..*.*(..))")
    public void consolePointcut() {
    }

    @Before("consolePointcut()")
    //前置通知 -- 业务代码之前 执行的内容
    public void doBefore(JoinPoint joinPoint) throws Throwable
    {
       if(!"TRUE".equalsIgnoreCase(env.getDebug())) {
    		return;
    	}
        // 开始打印请求日志
        HttpServletRequest request = ServletKit.getRequest();
        Signature signature = joinPoint.getSignature();
        String name = signature.getName();
        //joinPoint 连接点 拿到方法 的参数
        // 打印请求信息
        LogKit.info("------------- 开始 -------------");
        LogKit.info("请求地址: {} {}", request.getRequestURL().toString(), request.getMethod());
        LogKit.info("类名方法: {}.{}", signature.getDeclaringTypeName(), name);
        LogKit.info("远程地址: {}", request.getRemoteAddr());
        //拿到nginx ip
        //RequestContext.setRemoteAddr(getRemoteIp(request));

        // 打印请求参数
        Object[] args = joinPoint.getArgs(); // 参数值
        // LOG.info("请求参数: {}", JSONObject.toJSONString(args));
        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) {
                continue;
            }
            arguments[i] = args[i];
        }
        // 排除字段，敏感字段或太长的字段不显示s*/
        String[] excludeProperties = {"password", "file"};
        PropertyPreFilter excludefilter = new SimplePropertyPreFilter(excludeProperties);
        LogKit.info("请求参数: {}", JSON.toJSONString(arguments, excludefilter));
    }

    @Around("consolePointcut()")
    //环绕通知 -- 在业务 内容 前面执行 和 后面执行
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    	 Object result = proceedingJoinPoint.proceed();
    	if(!"TRUE".equalsIgnoreCase(env.getDebug())) {
    		return result;
    	}
        long startTime = System.currentTimeMillis();
        // 排除字段，敏感字段或太长的字段不显示
        String[] excludeProperties = {"password", "file"};
        PropertyPreFilter excludefilter = new SimplePropertyPreFilter(excludeProperties);
        String temp = JSON.toJSONString(result, excludefilter);
        if(IsKit.isNotNullOrEmpty(temp)){
	        temp = StringEscapeUtils.unescapeEcmaScript(temp)
	        		.replace("\\\"","\"")
	        		.replace("\"{","{")
	        		.replace("}\"","}");
        }
       // if(IsUtil.isNotNull(temp) && temp.length() > 500) {
        //	temp = temp.substring(0, 500)+" ...... (共" + temp.length() +"个字节)";
        //}
        LogKit.info("返回结果: {}",temp);
        LogKit.info("------------- 结束 耗时：{} 毫秒 -------------", System.currentTimeMillis() - startTime);
        return result;
    }

}
