package com.uas.search.aop;

import javax.servlet.http.HttpServletRequest;

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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

import com.uas.search.util.IpHelper;
import com.uas.search.util.ObjectUtils;
import com.uas.search.util.StringUtils;

/**
 * 利用AOP处理Web请求日志
 * 
 * @author sunyj
 * @since 2016年12月20日 下午5:46:56
 */
@Aspect
@Component
@EnableAspectJAutoProxy
public class WebLogAspect {

	private Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

	@Pointcut("execution(* com.uas..controller.*.*(..))")
	public void log() {

	}

	@Before("log()")
	public void before(JoinPoint joinPoint) {
		StringBuilder stringBuilder = new StringBuilder("request... ");

		// 类名
		Object target = joinPoint.getTarget();
		Class<?> clazz = target.getClass();
		stringBuilder.append(clazz.getSimpleName());

		// 方法名
		Signature signature = joinPoint.getSignature();
		String methodName = signature.getName();
		stringBuilder.append(".").append(methodName);

		// 方法全名
		String methodString = signature.toString();
		// 取出参数类型
		String substring = methodString.substring(methodString.indexOf("(") + 1, methodString.lastIndexOf(")"));
		if (!StringUtils.isEmpty(substring)) {
			stringBuilder.append(": ");
			String[] strs = substring.split(",");
			Object[] args = joinPoint.getArgs();
			for (int i = 0; i < strs.length; i++) {
				if (strs[i].equals("HttpServletRequest")) {
					// 如果参数是HttpServletRequest，打印ip
					stringBuilder.append("ip=").append(IpHelper.getIp((HttpServletRequest) args[i]));
				} else if (strs[i].equals("HttpServletResponse")) {
					// 如果参数是HttpServletResponse，不做处理
					continue;
				} else {
					// 参数类型和参数值
					stringBuilder.append(strs[i]).append("=").append(ObjectUtils.toString(args[i]));
				}
				if (i != strs.length - 1) {
					stringBuilder.append(",");
				}
			}
		}
		logger.info(stringBuilder.toString());
	}

	@AfterReturning(value = "log()", returning = "result")
	public void afterReturning(JoinPoint joinPoint, Object result) {
		logger.info("result... " + result + "\n");
	}
}
