package com.sunda.spmsweb.aspect;

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.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

@Aspect
@Component
public class NoRepeatSubmitAspect {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Pointcut("@annotation(com.sunda.spmsweb.aspect.NoRepeatSubmit)")
    public void noRepeatSubmit() {
    }

    @Around("noRepeatSubmit()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)) {
            throw new RuntimeException("token不能为空");
        }
        String path = request.getServletPath();
        String key = "NoRepeatSubmit:" + token + ":" + path;
        boolean isExist = redisTemplate.hasKey(key);
        if (isExist) {
            throw new RuntimeException("请刷新页面再重新提交！Please refresh the page and resubmit！");
        }
        redisTemplate.opsForValue().set(key, "0", expireTime(joinPoint), TimeUnit.SECONDS);
        Object result = joinPoint.proceed();
        return result;
    }

    /**
     * 获取注解中的过期时间
     */
    private int expireTime(ProceedingJoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        NoRepeatSubmit annotation = method.getAnnotation(NoRepeatSubmit.class);
        return annotation.expireTime();
    }
}