package com.xhpc.payment.aspect;

import com.xhpc.common.core.annotation.NoRepeatSubmit;
import com.xhpc.common.core.web.domain.AjaxResult;
import com.xhpc.common.data.redis.StaticBeanUtil;
import com.xhpc.common.util.RequestUtils;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
public class RepeatSubmitAspect {

    private static final Logger LOGGER = LoggerFactory.getLogger(RepeatSubmitAspect.class);


    @Pointcut("@annotation(noRepeatSubmit)")
    public void pointCut(NoRepeatSubmit noRepeatSubmit) {

    }

    @Around("pointCut(noRepeatSubmit)")
    public Object around(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) throws Throwable {

        int lockSeconds = noRepeatSubmit.lockTime();

        HttpServletRequest request = RequestUtils.getRequest();
        Assert.notNull(request, "request can't be null");

        // 此处可以用token或者JSessionId
        String token = request.getHeader("Authorization");
        String path = request.getServletPath();
        String key = getKey(token, path);

        boolean isSuccess = StaticBeanUtil.tryLock(key, lockSeconds);
        LOGGER.info("tryLock key = [{}]", key);
        // 主要逻辑
        if (isSuccess) {
            LOGGER.info("tryLock success, key = [{}]", key);
            // 获取锁成功
            Object result;
//            try {
            // 执行进程
            result = pjp.proceed();
//            } finally {
            // 解锁
//                StaticBeanUtil.releaseLock(key);
//                LOGGER.info("releaseLock success, key = [{}]", key);
//            }
            return result;
        } else {
            // 获取锁失败，认为是重复提交的请求。
            LOGGER.info("tryLock fail, key = [{}]", key);
            return new AjaxResult(200, "重复请求，请稍后再试", null);
        }
    }

    private String getKey(String token, String path) {

        return "lock".concat(path.replace("/", ":").concat(token.replaceAll(" ", "")));
    }

}
