package com.palmnest.webapp.filter;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Base64;
import java.util.Map;
@Slf4j
public class LoginFilterAuthentication extends AbstractAuthenticationProcessingFilter {


    public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
    public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
    /** @deprecated */
    @Deprecated
    public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
    private String usernameParameter = "j_username";
    private String passwordParameter = "j_password";
    private boolean postOnly = true;
    private SessionAuthenticationStrategy sessionStrategy = new NullAuthenticatedSessionStrategy();
    //继承爷爷的原因是 我重新构造这个参数， 默认的是 /j_spring_security_check  我认为太丑
    public LoginFilterAuthentication() {
        super("/j_security_check");
    }

    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (this.postOnly &&!request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException(
                    "Authentication method not supported: " + request.getMethod());
        }
        UsernamePasswordAuthenticationToken authRequest=null;

        String username = request.getParameter("j_username");
        String passwd = request.getParameter("j_password");

        System.out.println("=======================myUsername:" + username + "   myPwd:" + passwd);
        log.info("=======================myUsername:" + username + "   myPwd:" + passwd);
        //如果不是token 登录，则base64解密
        if(StringUtils.isNotEmpty(passwd) && StringUtils.isNotEmpty(username) && username.startsWith("token!")==false ){
            try {
                byte[] bytes = Base64.getDecoder().decode(passwd);
                passwd = new String(bytes);
            }catch (Exception ex)
            {
                log.error("base64 decode passwd error:" + ex.toString());
            }

            log.info("=======================decodepwd:" + passwd);
        }
        authRequest = new UsernamePasswordAuthenticationToken(username, passwd);

        // Allow subclasses to set the "details" property
        setDetails(request, authRequest);
        // 执行校验(使用DaoAuthenticationProvider进行校验)
        return this.getAuthenticationManager().authenticate(authRequest);
    }



    protected String obtainPassword(HttpServletRequest request) {
        return request.getParameter(this.passwordParameter);
    }

    protected String obtainUsername(HttpServletRequest request) {
        return request.getParameter(this.usernameParameter);
    }

    protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
        authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
    }

    public void setUsernameParameter(String usernameParameter) {
        Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
        log.info("Username parameter must not be empty or null");
        this.usernameParameter = usernameParameter;
    }

    public void setPasswordParameter(String passwordParameter) {
        Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
        log.info("Password parameter must not be empty or null");
        this.passwordParameter = passwordParameter;
    }

    public void setPostOnly(boolean postOnly) {
        this.postOnly = postOnly;
    }




}