package cn.superdesk.uniorder.openapi.aop.qchjc;

import cn.superdesk.uniorder.common.exception.OpenApiException;
import cn.superdesk.uniorder.openapi.annotation.QchjcRequestLog;
import cn.superdesk.uniorder.openapi.service.qchjc.log.RequestLogService;
import com.alibaba.fastjson2.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.lang.reflect.UndeclaredThrowableException;

/**
 * @author xc
 * @description
 * @date 2022/3/31 16:52
 */
@Aspect
@Component
@Slf4j
@RequiredArgsConstructor
public class RequestLogAspect {

    private final RequestLogService requestLogService;

    /**
     * 成功返回通知
     *
     * @param joinPoint
     * @param qchjcRequestLog
     * @param data
     */
    @AfterReturning(value = "@annotation(qchjcRequestLog)", returning = "data")
    public void doAfter(JoinPoint joinPoint, QchjcRequestLog qchjcRequestLog, Object data) {
        String value = qchjcRequestLog.value();
        Object[] args = joinPoint.getArgs();
        log.info("调用 {} 方法成功，参数 : {}, 返回：{}", value, JSON.toJSONString(args[0]), data);
        //todo 记录
        requestLogService.record(1, value, JSON.toJSONString(args[0]), JSON.toJSONString(data));
    }

    /**
     * 异常通知
     *
     * @param joinPoint
     * @param qchjcRequestLog
     * @param e
     */
    @AfterThrowing(pointcut = "@annotation(qchjcRequestLog)", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, QchjcRequestLog qchjcRequestLog, Exception e) {
        String value = qchjcRequestLog.value();
        Object[] args = joinPoint.getArgs();
        String errorMsg = null;
        if (e instanceof UndeclaredThrowableException) {
            UndeclaredThrowableException exception = (UndeclaredThrowableException) e;
            Throwable cause = exception.getUndeclaredThrowable().getCause();
            if (cause instanceof OpenApiException) {
                OpenApiException openApiException = (OpenApiException) cause;
                errorMsg = openApiException.getMessage();
            } else {
                errorMsg = cause.getLocalizedMessage();
            }
        } else {
            errorMsg = e.getMessage();
        }
        log.info("调用 {} 方法异常，参数 : {}, 异常信息：{}", value, JSON.toJSONString(args[0]), errorMsg);
        //todo 记录
        requestLogService.record(0, value, JSON.toJSONString(args[0]), errorMsg);
    }


}
