package com.xhpc.general;


import com.xhpc.common.core.constant.CacheConstants;
import com.xhpc.common.core.utils.SecurityUtils;
import com.xhpc.common.core.utils.StringUtils;
import com.xhpc.common.redis.service.RedisService;
import com.xhpc.system.api.model.LoginUser;
import org.apache.commons.beanutils.BeanUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/*
 * TODO AO切面，插入创建人，创建时间，修改人，修改时间
 * @author fjd
 * @date 2020-07-09 11:59
 */
@Aspect
@Component
@Configuration
public class DaoAspect {

    private static final String CREATE_USER = "createBy";
    private static final String CREATE_TIME = "createTime";
    private static final String UPDATE_USER = "updateBy";
    private static final String UPDATE_TIME = "updateTime";
    private static final String TENANT_ID = "tenantId";

    @Pointcut("execution(* com.xhpc..*.update*(..))")
    public void daoUpdate() {

    }

    @Pointcut("execution(* com.xhpc..*.insert*(..))")
    public void daoCreate() {

    }

    @Autowired
    private RedisService redisService;

    @Around("daoUpdate()")
    public Object doAroundUpdate(ProceedingJoinPoint point) throws Throwable {

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            return point.proceed();
        }
        HttpServletRequest request = attributes.getRequest();
        try {
            String token = request.getHeader(CacheConstants.HEADER);
            token = token.substring(7);
            LoginUser loginUser = new LoginUser();
            try {
                loginUser = redisService.getCacheObject(CacheConstants.LOGIN_TOKEN_KEY + token);
            } catch (Exception e) {
            }
            String userName = "";
            try {
                userName = SecurityUtils.getUsername();
            } catch (Exception e) {
            }
            if (StringUtils.isEmpty(userName)) {
                userName = loginUser.getUsername();
            }
            if (StringUtils.isEmpty(userName)) {
                userName = "admin";
            }
            if (userName != null) {
                Object[] objects = point.getArgs();
                if (objects != null && objects.length > 0) {
                    for (Object arg : objects) {
                        if (isProperty(arg, UPDATE_USER) && StringUtils.isEmpty(BeanUtils.getProperty(arg, UPDATE_USER))) {
                            BeanUtils.setProperty(arg, UPDATE_USER, userName);
                        }
                        if (isProperty(arg, UPDATE_TIME) && StringUtils.isEmpty(BeanUtils.getProperty(arg, UPDATE_TIME))) {
                            BeanUtils.setProperty(arg, UPDATE_TIME, new Date());
                        }
                    }
                }
            }
        } catch (Exception e) {
        }
        Object object = point.proceed();
        return object;

    }

    @Around("daoCreate()")
    public Object doAroundCreate(ProceedingJoinPoint point) throws Throwable {

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            return point.proceed();
        }
        HttpServletRequest request = attributes.getRequest();
        try {
            Object[] objects = point.getArgs();
            if (objects != null && objects.length > 0) {
                for (Object arg : objects) {
                    String token = request.getHeader(CacheConstants.HEADER);
                    token = token.substring(7);
                    LoginUser loginUser = new LoginUser();
                    try {
                        loginUser = redisService.getCacheObject(CacheConstants.LOGIN_TOKEN_KEY + token);
                    } catch (Exception e) {
                    }
                    String userName = "";
                    try {
                        userName = SecurityUtils.getUsername();
                    } catch (Exception e) {
                    }
                    if (StringUtils.isEmpty(userName)) {
                        userName = loginUser.getUsername();
                    }
                    if (StringUtils.isEmpty(userName)) {
                        userName = "admin";
                    }
                    Date date = new Date();
                    if (isProperty(arg, CREATE_USER) && StringUtils.isEmpty(BeanUtils.getProperty(arg, CREATE_USER))) {
                        BeanUtils.setProperty(arg, CREATE_USER, userName);
                    }
                    if (isProperty(arg, UPDATE_USER) && StringUtils.isEmpty(BeanUtils.getProperty(arg, UPDATE_USER))) {
                        BeanUtils.setProperty(arg, UPDATE_USER, userName);
                    }

                    if (isProperty(arg, CREATE_TIME) && StringUtils.isEmpty(BeanUtils.getProperty(arg, CREATE_TIME))) {
                        BeanUtils.setProperty(arg, CREATE_TIME, date);
                    }
                    if (isProperty(arg, UPDATE_TIME) && StringUtils.isEmpty(BeanUtils.getProperty(arg, UPDATE_TIME))) {
                        BeanUtils.setProperty(arg, UPDATE_TIME, date);
                    }

                    if (isProperty(arg, TENANT_ID) && StringUtils.isEmpty(BeanUtils.getProperty(arg, TENANT_ID))) {
                        BeanUtils.setProperty(arg, TENANT_ID, loginUser.getTenantId());
                    }
                }
            }
        } catch (Exception e) {
        }
        Object object = point.proceed();
        return object;
    }

    public static boolean isProperty(Object bean, String field) {

        return StringUtils.isProperty(bean, field);
    }

}
