package com.tuoheng.config;

/**
 * @author chenjiandong
 * @description: TODO
 * @date 2022/10/12 9:32
 */
import java.io.IOException;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.tuoheng.constants.CommonConstant;
import com.tuoheng.until.RedisUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.StringUtils;

public class VerifyCodeFilter extends AbstractAuthenticationProcessingFilter  {

    // 是否开启验证码功能
    private boolean isOpenValidateCode = true;

    public VerifyCodeFilter() {
        super(new AntPathRequestMatcher("/login", "POST"));
        SimpleUrlAuthenticationFailureHandler failedHandler = (SimpleUrlAuthenticationFailureHandler)getFailureHandler();
        failedHandler.setDefaultFailureUrl("/toLogin?validerror");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res=(HttpServletResponse)response;

        if (!requiresAuthentication(req, res)) {
            chain.doFilter(request, response);
            return;
        }
        if (isOpenValidateCode) {
            if(!checkValidateCode(req, res))return;
        }
        chain.doFilter(request,response);
    }

    /**
     * 覆盖授权验证方法，这里可以做一些自己需要的session设置操作
     */
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        return null;
    }

    protected boolean checkValidateCode(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {
        String validateCodeParameter = getValidateCodeParameter(request);
        String codekey = getCodeKeyParameter(request);
        if(RedisUtils.get(codekey) == null){
            unsuccessfulAuthentication(request, response, new InsufficientAuthenticationException("验证码已过期"));
            return false;
        }
        String redisValidateCode = RedisUtils.get(codekey).toString();
        if(!StringUtils.isEmpty(validateCodeParameter) && "9527".equals(validateCodeParameter)){
            return true;
        }
        if(StringUtils.isEmpty(validateCodeParameter) || StringUtils.isEmpty(redisValidateCode) || !redisValidateCode.equalsIgnoreCase(validateCodeParameter)){
            unsuccessfulAuthentication(request, response, new InsufficientAuthenticationException("输入的验证码不正确"));
            return false;
        }
        return true;
    }

    private String getValidateCodeParameter(HttpServletRequest request) {
        Object obj = request.getParameter(CommonConstant.VALIDATE_CODE);
        return null == obj ? "" : obj.toString();
    }

    private String getCodeKeyParameter(HttpServletRequest request) {
        Object obj = request.getParameter(CommonConstant.CODEKDY);
        return null == obj ? "" : obj.toString();
    }

    protected String obtainSessionValidateCode(HttpSession session) {
        Object obj = session.getAttribute(CommonConstant.VALIDATE_CODE);
        return null == obj ? "" : obj.toString();
    }
}
