package com.yanzuoguang.cloud.aop;

import com.yanzuoguang.util.contants.ResultConstants;
import com.yanzuoguang.util.exception.CodeException;
import com.yanzuoguang.util.exception.ExceptionHelper;
import com.yanzuoguang.util.vo.ResponseResult;
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.stereotype.Component;

/**
 * 接口切面,用于验证接口回调返回参数
 */
@Aspect
@Component
public class FeignAspect extends HttpAspectUtil {

    private static final Logger logger = LoggerFactory.getLogger(FeignAspect.class);

    /**
     * AOP的表达式
     */
    @Pointcut("execution(* *..feign..*Feign.*(..))")
    public void feignAspect() {
    }

    /**
     * 执行环形切面
     *
     * @param joinPoint
     * @return
     */
    @Around(value = "feignAspect()")
    public Object requestFeignAround(ProceedingJoinPoint joinPoint) throws Throwable {
        String name = joinPoint.getSignature().getName();
        Object result = null;
        long start = System.currentTimeMillis();
        try {
            logger.info("[ {} ] feign params is {}", name, joinPoint.getArgs());
            result = joinPoint.proceed();

            // 假如是标准格式,则验证接口是否成功,不成功则抛出异常
            if (result instanceof ResponseResult) {
                ResponseResult responseResult = (ResponseResult) result;
                if (!ResultConstants.SUCCESS.equals(responseResult.getCode())) {
                    throw new CodeException(responseResult.getCode(), responseResult.getMessage(), responseResult.getTarget());
                }
            }

            // 记录服务调用时间,请求日志
            long end = System.currentTimeMillis();
            logger.info("[ {} ] feign time ({})ms, result is {}", name, (end - start), result);

            return result;
        } catch (Exception e) {
            long end = System.currentTimeMillis();
            logger.error("[ {} ] feign time ({})ms , error {}", name, (end - start), e);
            if (e instanceof CodeException) {
                throw e;
            } else {
                ResponseResult responseResult = ExceptionHelper.getError(e);
                throw new CodeException(responseResult.getCode(), responseResult.getMessage(), responseResult.getTarget());
            }
        }
    }


}