package com.bonus.hn.bearing.capacity.backstage.manager.filter;

import com.bonus.hn.bearing.capacity.backstage.manager.advice.VerifyCodeException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @author bonus
 */
public class VerifyFilter extends OncePerRequestFilter {

    private static final PathMatcher pathMatcher = new AntPathMatcher();

    private StringRedisTemplate stringRedisTemplate;

    private AuthenticationFailureHandler authenticationFailureHandler;

    private String prefix;

    public VerifyFilter() {}

    public VerifyFilter(StringRedisTemplate stringRedisTemplate, String prefix, AuthenticationFailureHandler authenticationFailureHandler) {
        this.stringRedisTemplate = stringRedisTemplate;
        this.prefix = prefix;
        this.authenticationFailureHandler = authenticationFailureHandler;

    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 拦截 /login的POST请求
        if(isProtectedUrl(request)) {
            // 图片验证码的 key
            String uuid = request.getParameter("uuid");
            // 图片验证码的 value
            String vCode = request.getParameter("verifyCode");
            String s = validateVerify(request, uuid, vCode);
            if(!"".equals(s)) {
                authenticationFailureHandler.onAuthenticationFailure(request, response,new VerifyCodeException(s));
            } else {
                filterChain.doFilter(request,response);
            }
        } else {
            filterChain.doFilter(request,response);
        }
    }

    /**
     * 验证验证码合法性
     * @param uuid  验证key
     * @param vCode 验证值
     * @return
     */
    private String validateVerify(HttpServletRequest request, String uuid, String vCode) {
        // 查询验证码
        String code = stringRedisTemplate.opsForValue().get(prefix + uuid);

        // 清除验证码
        stringRedisTemplate.delete(prefix + uuid);

        if (StringUtils.isBlank(code)) {
            //手动设置异常
            return "验证码已过期";
        }
        if (StringUtils.isBlank(vCode) || !vCode.equalsIgnoreCase(code)) {
            return "验证码错误";
        }

        logger.info("验证码：" + code + "用户输入：" + vCode);
        return "";
    }

    /**
     * 拦截 /login的POST请求
     * @param request request
     * @return boolean
     */
    private boolean isProtectedUrl(HttpServletRequest request) {
        return "POST".equals(request.getMethod()) && pathMatcher.match("/login", request.getServletPath());
    }

}

