package com.lutao.cloud.common.log.aspect;

import com.google.gson.Gson;
import com.lutao.cloud.common.log.annotation.SysLog;
import com.lutao.cloud.common.log.event.SysLogEvent;
import com.lutao.cloud.common.log.util.LogTypeEnum;
import com.lutao.cloud.common.log.util.SysLogUtils;
import com.lutao.cloud.admin.api.dto.SysLogDTO;
import com.lutao.cloud.common.core.util.KeyStrResolver;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import org.slf4j.MDC;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 操作日志使用spring event异步入库
 */
@Slf4j
@Aspect
@RequiredArgsConstructor
public class SysLogAspect{

    private final ApplicationEventPublisher publisher;

    private final KeyStrResolver tenantKeyStrResolver;

    @SneakyThrows
    @Around("@annotation(sysLog)")
    public Object around(ProceedingJoinPoint point, SysLog sysLog){
        // 开始打印请求日志
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 请求地址
        String url = request.getRequestURL().toString();
        // httpMethod
        String httpMethod = request.getMethod();
        // IP
        String IP = request.getRemoteAddr();
        // 打印全路径及执行方法
        String strClassName = point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName();
        // 打印入参
        String requestArgs = new Gson().toJson(point.getArgs());
        // 打印出参
        String responseArgs = "";
        // 打印userId
        String uid = MDC.get("uid");
        String logMsg = "[IP=" + IP + "] " +
                "[UID=" + uid + "] " +
                "[URI=" + url + "] " +
                "[METHOD=" + httpMethod + "] " +
                "[ClassMethod=" + strClassName + "] " +
                "[REQUEST=" + requestArgs + "] ";
        log.info(logMsg);

        SysLogDTO logDTO = SysLogUtils.getSysLog();
        logDTO.setTitle(sysLog.value());
        // 发送异步日志事件
        Long startTime = System.currentTimeMillis();
        Object obj;
        try{
            obj = point.proceed();
          //  responseArgs = new Gson().toJson(obj);
        } catch (Exception e){
            logDTO.setType(LogTypeEnum.ERROR.getType());
            logDTO.setException(e.getMessage());
            throw e;
        } finally{
            Long endTime = System.currentTimeMillis();
            logDTO.setTime(endTime - startTime);
            logDTO.setTenantId(Integer.parseInt(tenantKeyStrResolver.key()));
            publisher.publishEvent(new SysLogEvent(logDTO));
        }
        return obj;
    }

}
