package com.fs.core.interceptor.impl;

import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;
import com.fs.common.constant.Constants;
import com.fs.common.filter.RepeatedlyRequestWrapper;
import com.fs.common.utils.StringUtils;
import com.fs.common.utils.http.HttpHelper;
import com.fs.core.interceptor.RepeatSubmitInterceptor;

/**
 * 判断请求url和数据是否和上一次相同，
 * 如果和上次相同，则是重复提交表单。 有效时间为10秒内。
 */
@Slf4j
@Component
public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
{

    // 令牌自定义标识
    @Value("${token.header}")
    private String header;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    @Qualifier("prevent-resubmit")
    private DefaultRedisScript<Boolean> preventResubmitScript;

    /**
     * 间隔时间，单位:秒 默认10秒
     *
     * 两次相同参数的请求，如果间隔时间大于该参数，系统不会认定为重复提交的数据
     */
    private int intervalTime = 10;


    @SuppressWarnings("unchecked")
    @Override
    public boolean isRepeatSubmit(HttpServletRequest request)
    {
       return this.isRepeatSubmit(request,this.intervalTime);
    }

    @Override
    public boolean isRepeatSubmit(HttpServletRequest request, Integer intervalTime) {
        String nowParams = "";
        if (request instanceof RepeatedlyRequestWrapper)
        {
            RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request;
            nowParams = HttpHelper.getBodyString(repeatedlyRequest);
        }

        // body参数为空，获取Parameter的数据
        if (StringUtils.isEmpty(nowParams))
        {
            nowParams = JSON.toJSONString(request.getParameterMap());
        }
        // 请求地址（作为存放cache的key值）
        String url = request.getRequestURI();

        // 唯一值（没有消息头则使用请求地址）
        String submitKey = request.getHeader(header);
        if (StringUtils.isEmpty(submitKey))
        {
            submitKey = url;
        }

        // 唯一标识（指定key + 消息头）
        String cache_repeat_key = Constants.REPEAT_SUBMIT_KEY + submitKey;
        // 当前时间戳
        long currentTimeMillis = System.currentTimeMillis();

        // 执行Lua脚本
        List<String> keys = Arrays.asList(cache_repeat_key, url);

        log.info("调用lua参数: {} {} {} {} {}",preventResubmitScript,keys,nowParams,currentTimeMillis,intervalTime);

        Boolean result = (Boolean) redisTemplate.execute(
                preventResubmitScript,
                keys,
                nowParams,
                currentTimeMillis,
                intervalTime
        );

        return result != null && result;
    }
}
