package xiaoqu.home.open.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import xiaoqu.home.open.model.db1.User;
import xiaoqu.home.open.model.db2.ChangeLog;
import xiaoqu.home.open.service.db2.ChangeLogService;
import xiaoqu.home.open.utils.UserUtils;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.Date;

/**
 *
 */
@Aspect
@Component
public class SetUserAspect {
	@Autowired
	private ChangeLogService changeLogService;

	@Pointcut("execution(public * xiaoqu.home.open.service..*.save(..))")
	public void pointCutSave() {

	}

	@Pointcut("execution(public * xiaoqu.home.open.service..*.updateById(..))")
	public void pointCutUpdate() {

	}

	@Before("pointCutSave()")
	public void doSaveBefore(JoinPoint joinPoint) throws IllegalAccessException {

		HttpServletRequest request = httpServletRequest();
		if(request==null){
			return;

		}
		Object[] args = joinPoint.getArgs();
		Class<?> aClass = args[0].getClass();
		if (aClass.getSimpleName().toLowerCase().contains("log") && !aClass.getSimpleName().toLowerCase().contains("modifylog")) {
			return;
		}
		User user = UserUtils.getUser(request);
		if (user == null) {
			return;
		}

		Field[] declaredFields = aClass.getDeclaredFields();
		for (Field field : declaredFields) {
			if (field.getName().contains("create")) {
				if (field.getName().equals("createName")) {
					field.setAccessible(true);
					field.set(args[0], user.getName());
					continue;
				}
				if (field.getName().equals("createTime")) {
					field.setAccessible(true);
					field.set(args[0], new Date());
					continue;
				}
				if (field.getName().equals("createId")) {
					field.setAccessible(true);
					field.set(args[0], user.getId());
					continue;
				}
			}

		}
		Assert.notNull(request, "request can not null");
		insertChangeLog(user, 0, aClass.getSimpleName(), args[0].toString());
	}

	@Before("pointCutUpdate()")
	public void doUpdateBefore(JoinPoint joinPoint) throws IllegalAccessException {
		HttpServletRequest request = httpServletRequest();
		if(request==null){
			return;
		}
		Object[] args = joinPoint.getArgs();
		Class<?> aClass = args[0].getClass();
		User user = UserUtils.getUser(request);
		if (user == null) {
			return;
		}
		Field[] declaredFields = aClass.getDeclaredFields();
		for (Field field : declaredFields) {
			field.getName();
			if (field.getName().equals("modifyName")) {
				field.setAccessible(true);
				field.set(args[0], user.getName());
				continue;
			}
			if (field.getName().equals("modifyTime")) {
				field.setAccessible(true);
				field.set(args[0], new Date());
				continue;
			}
			if (field.getName().equals("modifyId")) {
				field.setAccessible(true);
				field.set(args[0], user.getId());
				continue;
			}
		}

		insertChangeLog(user, 1, aClass.getSimpleName(), args[0].toString());
	}

	/**
	 * 获得request对象
	 *
	 * @return
	 */
	private HttpServletRequest httpServletRequest() {
		ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		if (requestAttributes==null) {
			return null;
		}
		return requestAttributes.getRequest();
	}

	/**
	 * 获得request对象
	 *
	 * @return
	 */
	private void insertChangeLog(User user, Integer type, String table, String context) {
		ChangeLog changeLog = new ChangeLog();
		changeLog.setCreateId(user.getId());
		changeLog.setCreateName(user.getName());
		changeLog.setCreateTime(user.getCreateTime());
		changeLog.setTableName(table);
		changeLog.setContext(context);
		changeLog.setActionType(type);
		changeLog.setSource(0);

		try {
			changeLogService.save(changeLog);
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}
	}

}
