package com.zcloud.common.filter;

import com.alibaba.fastjson.JSONObject;
import com.zcloud.common.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import javax.servlet.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;


@Configuration
public class QpsLimitFilterConfiguration {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Bean
    public FilterRegistrationBean<Filter> contextQpsFilterRegistrationBean() {
        FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
        registration.setFilter(QpsLimitFilter());
        registration.addUrlPatterns("/*");
        registration.setName("QpsLimitFilter");
        registration.setOrder(2);
        return registration;
    }


    @Bean
    public Filter QpsLimitFilter() {
        return new QpsLimitFilter(redisTemplate);
    }

    private class QpsLimitFilter implements Filter {
        private static final String REDIS_KEY_USED = "user_request_count:";
        private static final String REDIS_KEY_MAX = "user_request_count_max:";
        private static final long DEFAULT_MAX_QPS = 10000000; // 最大QPS设为10
        private static final int EXPIRE_TIME_IN_SECONDS = 1; // 过期时间设为1秒
        private RedisTemplate<String, Object> redisTemplate;

        public QpsLimitFilter(RedisTemplate<String, Object> redisTemplate) {
            this.redisTemplate = redisTemplate;
        }

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            String corpinfoId = request.getParameter("corpinfoId");
            String redisKey = REDIS_KEY_USED + corpinfoId;

            ValueOperations<String, Object> ops = redisTemplate.opsForValue();
            Long count = ops.increment(redisKey, 1L); // 自增计数器

            // 从 Redis 中获取对应 corpinfo_id 的 MAX_QPS 值
            Object maxQpsObj = redisTemplate.opsForValue().get(REDIS_KEY_MAX + corpinfoId);
            Long maxQps = DEFAULT_MAX_QPS;
            if(maxQpsObj == null){
                // TODO 查询 数据库内的值
            }else if (maxQpsObj instanceof String) {
                maxQps = Long.parseLong((String) maxQpsObj);
            } else {
                // 处理异常情况，比如类型不匹配
                maxQps = DEFAULT_MAX_QPS;
            }

            if (count != null && count > maxQps) {
                // 超过最大QPS，返回错误信息或者进行其他处理
                returnFail("请求过于频繁，请稍后再试",response);
                return;
            }

            // 第一次访问时设置过期时间
            if (count == 1) {
                redisTemplate.expire(redisKey, EXPIRE_TIME_IN_SECONDS, TimeUnit.SECONDS);
            }

            chain.doFilter(request, response);
        }

        private void returnFail(String msg, ServletResponse response) throws IOException {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            PrintWriter out = response.getWriter();
            String result = JSONObject.toJSONString(R.error(msg));
            out.println(result);
            out.flush();
            out.close();
        }


        @Override
        public void init(FilterConfig config) throws ServletException {
        }
        @Override
        public void destroy() {
        }
    }
}


