package com.yxcheng.token.common.aop;


import com.alibaba.fastjson.JSONObject;
import com.yxcheng.token.common.annotation.LogT;
import com.yxcheng.token.utils.MapUtil;
import com.yxcheng.token.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
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.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Aspect
@Component
public class LogAop {

    //切入点
    @Pointcut("@annotation(com.yxcheng.token.common.annotation.LogT)")
    public void log(){

    }

//    @After("log()")
//    public void afterExec(JoinPoint joinpoint) throws Throwable{
//    }
//
//    @Before("log()")
//    public void beforeExec(JoinPoint joinpoint) throws Throwable{
//    }

    @Around(value = "log() && @annotation(logt)")
    public Object aroundExec(ProceedingJoinPoint point, LogT logt) throws Throwable{

        //请求开始时间
        long start = System.currentTimeMillis();
        //请求参数
        Map paramsMap = new HashMap();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String contentType = request.getContentType();//获取请求的content-type
        if(StringUtils.isNotBlank(contentType) && (contentType.contains("multipart/form-data") || contentType.contains("application/json"))){//文件上传请求 json传输 *特殊请求
            //上传文件获取第一个入参对象。
            Object[] args = point.getArgs();
            if(args.length>0){
                paramsMap = MapUtil.objectToMap(point.getArgs()[0]);
            }
        }else{//非文件上传请求
            paramsMap = request.getParameterMap();
        }
        log.info(start + " method:"+point.toShortString()+";params:"+ JSONObject.toJSONString(paramsMap) + " is start!");
        //执行方法
        Object result = point.proceed();
        //请求耗时
        long time = System.currentTimeMillis() - start;
        //输出日志
        String logResult = JSONObject.toJSONString(result);
        if(logt.value().equals(LogT.LOG_VIEW_PART)) {
            logResult = sublog(logResult);
        }
        log.info(start + " method:"+ point.toShortString() +";response:"+ logResult +" is end! cost:["+time+"ms]");

        return result;

    }

    private String sublog(String log) {
        if(StringUtil.isNotEmpty(log) && log.length()>305) {
            log = log.substring(0, 300) + "...";
        }
        return log;
    }
}
