package com.hotent.base.aop;

import com.hotent.base.model.CommonResult;
import com.hotent.base.util.BeanUtils;
import com.hotent.base.util.ThreadMethodUtil;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 全局接口事件异步处理切面
 *
 * @company 广州宏天软件股份有限公司
 * @author yijj
 * @email yijj@jee-soft.cn
 * @date 2022年05月20日
 */
@Aspect
@Component
public class InterfaceEventPostAsyncAspect {
	private Logger logger = LoggerFactory.getLogger(getClass());


	private static final String POST_ASYNC_POINT = "@annotation(com.hotent.base.annotation.InterfaceEventPostAsync)";

	/**
     * 后置返回通知
     * 这里需要注意的是:
     * 如果参数中的第一个参数为JoinPoint，则第二个参数为返回值的信息
     * 如果参数中的第一个参数不为JoinPoint，则第一个参数为returning中对应的参数
     * returning 限定了只有目标方法返回值与通知方法相应参数类型时才能执行后置返回通知，否则不执行，对于returning对应的通知方法参数为Object类型将匹配任何目标返回值
	 * @throws SecurityException
	 * @throws NoSuchFieldException
     */
    @AfterReturning(value=POST_ASYNC_POINT,returning = "object")
    public void doAfterReturningAdvice1(Object object) throws Exception {
		CommonResult result = null;
		if (object instanceof CommonResult) {
			result = (CommonResult) object;
		}
		if (object instanceof CompletableFuture) {
			result = (CommonResult) ((CompletableFuture) object).get();
		}
		if (BeanUtils.isNotEmpty(result) && result.getState()) {
			List<ObjectFactory<?>> factoryList = ThreadMethodUtil.getMapFactory(ThreadMethodUtil.POST_ASYNC, true);
			if (BeanUtils.isNotEmpty(factoryList)) {
				logger.info("全局接口事件异步请求");
				factoryList.forEach(ObjectFactory::getObject);
			}
		}

	}

}
