package com.glxp.mipsdl.aspect;


import cn.hutool.core.exceptions.ExceptionUtil;
import com.alibaba.fastjson.JSONObject;
import com.glxp.mipsdl.service.system.SysErpLogService;
import lombok.extern.slf4j.Slf4j;
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.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 日志切面
 */
@Slf4j
@Aspect
@Component
public class LogAspect {

    @Resource
    private SysErpLogService logService;

    //controller接口切面
    @Pointcut(value = "execution(public * com.glxp.mipsdl.controller..*(..))")
    public void execute() {

    }

    @Around("execute()")
    public Object doAround(ProceedingJoinPoint point) {
        Date createTime = new Date();

        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();

        String uri = httpServletRequest.getRequestURI();
        String method = httpServletRequest.getMethod();
        String queryString = httpServletRequest.getQueryString();
        Object[] args = point.getArgs();
        StringBuilder params = new StringBuilder();
        if (args.length > 0) {
            if ("POST".equals(method)) {
                for (Object o : args) {
                    if (null != o) {
                        Map map = getKeyAndValue(o);
                        if (!map.isEmpty()) {
                            params.append(JSONObject.toJSONString(map));
                        }
                    }
                }

            } else if ("GET".equals(method)) {
                params = new StringBuilder(queryString);
            }
        }

        long beginTime = System.currentTimeMillis();
        log.info("请求URI:{},方法:{},参数:{}", uri, method, params);

        Object proceed = null;
        try {
            proceed = point.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            log.error(ExceptionUtil.stacktraceToString(throwable));
        }
        String result = JSONObject.toJSONString(proceed);

        log.info("请求结束，返回参数:{}", result);
        long endTime = System.currentTimeMillis();
        long time = endTime - beginTime;
        log.info("执行时长：{}ms", time);

        logService.addInterfaceErpLog(createTime, uri, method, params.toString(), result, time);

        return proceed;
    }

    public static Map<String, Object> getKeyAndValue(Object object) {
        Map<String, Object> map = new HashMap<String, Object>();
        Class uCla = (Class) object.getClass();
        if (!(uCla.getPackage().getName().startsWith("com.glxp")
                || uCla.getPackage().getName().startsWith("java."))) {
            return map;
        }

        Field[] fs = uCla.getDeclaredFields();
        for (int i = 0; i < fs.length; i++) {
            Field f = fs[i];
            f.setAccessible(true);
            Object val = new Object();
            try {
                val = f.get(object);
                map.put(f.getName(), val);
            } catch (Exception e) {
                log.error(ExceptionUtil.stacktraceToString(e));
            }
        }
        return map;
    }


}
