/**
 * 
 */
package com.pcloud.common.core.aspect;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

import com.alibaba.fastjson.JSON;
import com.pcloud.common.utils.string.StringUtil;

/**
 * 
 * @author：songx
 * @date：2018年4月26日,下午2:32:36
 */
@Aspect
@Configuration
public class ParamLogAspect {

	/**
	 * 
	 */
	private final static Logger LOGGER = LoggerFactory.getLogger("");

	@Pointcut("execution(* com.pcloud..*(..))")
	public void bizPoint() {
	}

	/**
	 * 方法执行前以后执行
	 * 
	 * @param joinPoint
	 */
	@Before("bizPoint()")
	public void doBefore(JoinPoint joinPoint) {
		ParamLog paramLog = checkAnnotation(joinPoint);
		if (paramLog == null) {
			return;
		}
		Signature signature = joinPoint.getSignature();
		String methodName = signature.getName();
		String description = paramLog.description();
		description = StringUtil.isEmpty(description) ? paramLog.value() : description;
		StringBuffer msg = new StringBuffer(signature.getDeclaringTypeName()).append(" 【" + methodName + " before】");
		if (!StringUtil.isEmpty(description)) {
			msg.append(description);
		}
		if (!paramLog.isBefore()) {
			LOGGER.info(msg.toString());
		} else {
			String argsJson = JSON.toJSONString(joinPoint.getArgs());
			LOGGER.info(msg.append(",[Args]=").append(argsJson).toString());
		}
	}

	/**
	 * 方法执行完以后执行
	 * 
	 * @param object
	 */
	@AfterReturning(pointcut = "bizPoint()", returning = "result")
	public void doAfterReturn(JoinPoint joinPoint, Object result) {
		ParamLog paramLog = checkAnnotation(joinPoint);
		if (paramLog == null) {
			return;
		}
		Signature signature = joinPoint.getSignature();
		String methodName = signature.getName();
		String description = paramLog.description();
		description = StringUtil.isEmpty(description) ? paramLog.value() : description;
		StringBuffer msg = new StringBuffer(signature.getDeclaringTypeName())
				.append(" 【" + methodName + " afterReturn】");
		if (!StringUtil.isEmpty(description)) {
			msg.append(description);
		}
		if (!paramLog.isAfterReturn()) {
			LOGGER.info(msg.toString());
		} else {
			String resultJson = JSON.toJSONString(result);
			LOGGER.info(msg.append(",[result]=").append(resultJson).toString());
		}
	}

	private static ParamLog checkAnnotation(JoinPoint joinPoint) {
		// 获取方法签名
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		// java reflect相关类，通过反射得到注解
		Method method = signature.getMethod();
		if (!method.isAnnotationPresent(ParamLog.class)) {
			return null;
		}
		return method.getAnnotation(ParamLog.class);
	}

}
