package com.apobates.forum.member.impl;

import java.util.Optional;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.CodeSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.apobates.forum.event.elderly.ForumActionEnum;
import com.apobates.forum.event.elderly.MemberAction;
import com.apobates.forum.event.elderly.MemberActionDescriptor;
import com.apobates.forum.member.api.service.MemberActiveRecordsService;
import com.apobates.forum.member.entity.Member;
import com.apobates.forum.member.entity.MemberActiveRecords;
import com.apobates.forum.utils.ip.IPMatcher;
import com.apobates.forum.utils.ip.IPMatcher.IpMatchResult;

/**
 * Member模块中关于MemberAction注解拦截器
 * 
 * @author xiaofanku
 * @since 20190628
 */
@Aspect
public class MemberActionAspect {
	@Autowired
	private MemberActiveRecordsService memberActiveRecordsService;
	private final static Logger logger = LoggerFactory.getLogger(MemberActionAspect.class);
	
	@AfterReturning(pointcut = "@annotation(memberAction) && args(.., actionDescriptor)", returning = "retVal")
	public void check(
			JoinPoint joinPoint, 
			MemberAction memberAction, 
			MemberActionDescriptor actionDescriptor,
			Object retVal) throws Throwable {
		//
		Object[] paramValues = joinPoint.getArgs();
		CodeSignature signature = (CodeSignature) joinPoint.getStaticPart().getSignature();
		ForumActionEnum action = memberAction.action();
		String actionArgName = memberAction.argName();
		Class<?> actionTypeValue = memberAction.argType();
		logger.info(String.format("[MAT]arg name: %s, arg Type: %s, action: %s", actionArgName, actionTypeValue, action.getTitle()));
		// 返回值
		Optional<Object> data;
		boolean status = false;
		try {
			data = (Optional) retVal;
		} catch (ClassCastException e) {
			return;
		}
		if (data.isPresent()) { // 执行失败的
			status = true;
		}
		
		Long memberId = 0L;
		String names = Member.GUEST_NAMES;
		//
		String[] methodArguNames = signature.getParameterNames();
		for (int i = 0; i < paramValues.length; i++) {
			//logger.info(String.format("[MAT]method arg name: %s, method param Value: %s", methodArguNames[i], paramValues[i]));
			if (memberAction.argName().equals(methodArguNames[i])) {
				if (memberAction.argType() == Long.class) {
					memberId = (Long) paramValues[i];
				} else if (memberAction.argType() == String.class) {
					names = (String) paramValues[i];
				}
			}
		}
		//
		if(memberId>0 && Member.GUEST_NAMES == names){
			//取到names
			names = "*";
		}
		logger.info(String.format("[MAT]Agent: %s, Device: %s, Ip Address: %s", actionDescriptor.getAgent(), actionDescriptor.getDevice(), actionDescriptor.getIpAddr()));
		//
		MemberActiveRecords mar = new MemberActiveRecords(
				action, 
				status, 
				memberId, 
				names, 
				actionDescriptor.getIpAddr(),
				actionDescriptor.getReferrer(), 
				actionDescriptor.getToken(), 
				actionDescriptor.getDevice(),
				actionDescriptor.getAgent());
		try{
			Optional<IpMatchResult> mr = IPMatcher.getInstance().matchToResult(actionDescriptor.getIpAddr());
			if(mr.isPresent()){
				IpMatchResult imr = mr.get();
				mar.setIsp(imr.getIsp());
				mar.setProvince(imr.getProvince());
				mar.setDistrict(imr.getDistrict());
				mar.setCity(imr.getCity());
			}
		}catch(NullPointerException e){}
		memberActiveRecordsService.create(mar);
	}
}
