package com.dayou.aop;

import com.alibaba.fastjson.JSON;
import com.dayou.constants.JwtConstants;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.MessageFormat;

@Component
@Aspect
public class ApiLogAop {
	
    private static final Logger logger = LoggerFactory.getLogger(ApiLogAop.class);

    @Value("${spring.profiles.active}")
    private String active;
    
    /**
     * 记录controller出入参
     *
     * @param pjp
     * @return
     * @throws Throwable
     */
    @Around("execution(* com.dayou.controller..*.*(..))")
    public Object recordApiLog(ProceedingJoinPoint pjp) throws Throwable {
    	if("prod".equals(active)) {
    		return pjp.proceed();
    	}
        Object result = null;
        String className = null;
        String method = null;
        long start = System.currentTimeMillis();
        try {
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = requestAttributes.getRequest();
            String contentType = request.getContentType();
            String token = request.getHeader(JwtConstants.REST_TOKEN);
            className = pjp.getTarget().getClass().getName();
            method = pjp.getSignature().getName();
            Object[] args = pjp.getArgs();
            //打印参数
            if (contentType == null || (contentType != null && !contentType.contains("multipart/form-data"))) {
                logger.info(MessageFormat.format("class:{0},method:{1}, token:{2} ", className, method,  token));
                if(args!=null&&args.length>0){
                    for (int i = 0; i <args.length ; i++) {
                        Object arg=args[i];
                        //暂时忽略这几种类型
                        if(!(arg instanceof HttpServletRequest || arg instanceof HttpServletResponse || arg instanceof MultipartFile)){
                            logger.info(MessageFormat.format("inputParam{0}:{1}",(i+1),JSON.toJSONString(arg)));
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("打印入参异常", e);
        } finally {

        }
        try {
            result = pjp.proceed();
        } catch (Exception e) {
            logger.info(MessageFormat.format("cost:{0}ms,method:{1},outputParam:{2}", (System.currentTimeMillis() - start), method, JSON.toJSONString(e.getMessage())));
            throw e;
        }
        try {
            if (!(result instanceof byte[])) {
                logger.info(MessageFormat.format("class:{0},method:{1},outputParam:{2}", className, method, JSON.toJSONString(result)));
            }
            logger.info(MessageFormat.format("cost:{0}ms,method:{1}", (System.currentTimeMillis() - start), method));
        } catch (Exception e) {
            logger.error("打印出参异常", e);
        } finally {

        }
        return result;
    }

}
