package com.YuyeTech.TPlat.filter;


import cn.hutool.core.convert.Convert;
import com.YuyeTech.TPlat.VO.ResultVO;
import com.YuyeTech.TPlat.common.pojo.Result;
import com.YuyeTech.TPlat.constant.RedisConstant;
import com.YuyeTech.TPlat.enums.RedisType;
import com.YuyeTech.TPlat.enums.ResultEnum;
import com.YuyeTech.TPlat.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;

/**
 * @author:slambb
 * @date:2021/03/27
 */
@Slf4j
public class gameFilter implements Filter {
    @Value("${jwt.token}")
    private String tokenHeader;

    @Value("${server.servlet.context-path:}")
    private String contextPath;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    //添加redis 防止恶意请求
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    RedisSettingMap redisSettingMap;

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

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //处理跨域请求
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept , Authorization");

        log.info("********进入GameFilter过滤器********");
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        //登陆IP不在白名单
        String ipAddr = IpUtil.getIpAddr(req);
        String token = req.getHeader(tokenHeader);
        Integer platform = req.getIntHeader("platform"); //登录的平台

        String path = req.getServletPath();

        /**
         * game接口都需要限制访问
         */
        //设置5秒内可以访问5次，同一个接口
        String redisKey = "limit-req:".concat(req.getRequestURL().toString()).concat(":").concat(ipAddr);
        int _limitTime = 5, _limitCount = 10;
        if (!redisTemplate.hasKey(redisKey)) {
            redisTemplate.opsForValue().set(redisKey, String.valueOf(1), _limitTime, TimeUnit.SECONDS);
        } else {
            int increment = Convert.toInt(redisTemplate.opsForValue().get(redisKey));
            if (increment > _limitCount) {
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json; charset=utf-8");
                PrintWriter out = response.getWriter();
                out.print(JsonUtils.toJson(Result.of(null, false, ResultEnum.REDIS_IS_LOCK.getMessage(), ResultEnum.REDIS_IS_LOCK.getCode())));
                out.flush();
                out.close();
                return;
            } else {
                redisTemplate.opsForValue().set(redisKey, String.valueOf(++increment), _limitTime, TimeUnit.SECONDS);
            }
        }

        //登录，获取验证码，不用登录的接口
        // 存在game字段，需要检验token
        if (path.indexOf("login") > -1 ||
                path.indexOf("getCode") > -1 ||
                path.indexOf("dontLogin") > -1 ||
                path.indexOf("client_game") > -1 ||
                path.indexOf("findAll")>-1
        ) {
            //登录情况直接放行
            filterChain.doFilter(servletRequest, response);
            return;
        }

        log.info("token:"+token);
        if (null == token || token.isEmpty()) {
            //没有token信息
            ResultVO resultVO = ResultVOUtil.error(ResultEnum.TOKEN_DOES_NOT_EXIST);
            response.setCharacterEncoding("utf-8");
            response.getWriter().print(JsonUtils.toJson(resultVO));
            return;
        } else {
            //String authToken = token.substring(7);
            try {
                /**
                 * token使用redis管理，实时控制登录，下线等操作
                 */
//                String.format(RedisConstant.TOKEN_PREFIX, token)
                String userId = redisSettingMap.getValue(RedisType.TOKEN,token);
                //String userId = jwtTokenUtil.getUserIdFromToken(authToken);
                //if (!jwtTokenUtil.validateToken(authToken, userId)) {
                //    log.info("secret 不可靠，validateToken:{}", jwtTokenUtil.validateToken(authToken, userId));
                //}
                if (StringUtils.hasText(userId)) {
                    //传入userId和platform
                    filterChain.doFilter(new TokenRequestWrapper((HttpServletRequest) servletRequest, userId, platform), response);
                } else {
                    //不存在用户信息
                    ResultVO resultVO = ResultVOUtil.error(ResultEnum.TOKEN_DOES_NOT_HAVE_USER_ID);
                    response.setCharacterEncoding("utf-8");
                    response.getWriter().print(JsonUtils.toJson(resultVO));

                }
            } catch (Exception e) {
                ResultVO resultVO = ResultVOUtil.error(ResultEnum.TOKEN_FILTER_ERROR);
                response.setCharacterEncoding("utf-8");
                response.getWriter().print(JsonUtils.toJson(resultVO));
            }
            //catch (ExpiredJwtException e) {
            //    //token过期
            //    response.setCharacterEncoding("UTF-8");
            //    response.setContentType("application/json; charset=utf-8");
            //    PrintWriter out = response.getWriter();
            //    out.print(JsonUtils.toJson(Result.of(null, false, ResultEnum.TOKEN_OUT_OF_DATE.getMessage(), ResultEnum.TOKEN_OUT_OF_DATE.getCode())));
            //    out.flush();
            //    out.close();
            //}
            //catch (SignatureException e) {
            //    //secret校验密钥不对
            //    response.setCharacterEncoding("UTF-8");
            //    response.setContentType("application/json; charset=utf-8");
            //    PrintWriter out = response.getWriter();
            //    out.print(JsonUtils.toJson(Result.of(authToken, false, ResultEnum.TOKEN_IS_ILLEGAL.getMessage(), ResultEnum.TOKEN_IS_ILLEGAL.getCode())));
            //    out.flush();
            //    out.close();
            //}

        }

    }
}
