package ink.wgink.common.aspect;

import ink.wgink.common.component.SecurityComponent;
import ink.wgink.pojo.app.AppTokenUser;
import ink.wgink.pojo.bos.UserInfoBO;
import ink.wgink.properties.LoggingProperties;
import ink.wgink.util.ReflectUtil;
import ink.wgink.util.log.LogUtil;
import ink.wgink.util.request.RequestUtil;
import org.apache.commons.lang3.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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * @ClassName: ApiLogAspect
 * @Description: 接口日志切面
 * @Author: WangGeng
 * @Date: 2019/3/14 9:33 AM
 * @Version: 1.0
 **/
@Aspect
@Component
@Order(2)
public class ApiLogAspect {

    private static final Logger LOG = LoggerFactory.getLogger(ApiLogAspect.class);
    @Autowired
    private SecurityComponent securityComponent;
    @Autowired
    private LoggingProperties loggingProperties;

    /**
     * api切入点
     */
    @Pointcut("execution(public * *..controller..*.*(..))")
    public void apiLogCutPoint() {
    }

    @Around("apiLogCutPoint()")
    public Object apiLogAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        if (loggingProperties == null || !loggingProperties.getEnableApiLog()) {
            return proceedingJoinPoint.proceed();
        }
        return apiResult(proceedingJoinPoint);
    }

    private Object apiResult(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object result;
        try {
            long startTime = System.currentTimeMillis();
            result = proceedingJoinPoint.proceed();
            long endTime = System.currentTimeMillis();
            log(startTime, endTime);
        } catch (Throwable e) {
            throw e;
        }
        return result;
    }

    /**
     * 生成日志
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     */
    private void log(long startTime, long endTime) {
        HttpServletRequest request = RequestUtil.getRequest();
        String uri = request.getRequestURI().replace(request.getContextPath(), "");
        if (uri.startsWith("/route")) {
            return;
        }
        String token = request.getHeader("token");
        UserInfoBO userInfoBO = securityComponent.getCurrentUser();
        String userId = "";
        String userName = "";
        if (userInfoBO != null) {
            // 登录系统的用户
            userId = userInfoBO.getUserId();
            userName = userInfoBO.getUserName();
        } else if (!StringUtils.isBlank(token)) {
            // APP用户
            try {
                AppTokenUser appTokenUser = securityComponent.getAppTokenUser(token);
                if (appTokenUser != null) {
                    userId = appTokenUser.getId();
                    userName = appTokenUser.getName();
                }
            } catch (ReflectUtil.ReflectException e) {
                e.printStackTrace();
            }
        }
        LogUtil.apiLog(request, uri, startTime, endTime, userId, userName);
    }

}
