package com.philisense.www.filter;

import com.philisense.www.constant.Constants;
import com.philisense.www.pojos.entity.JwtUser;
import com.philisense.www.service.JwtUserDetailsService;
import com.philisense.www.utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
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;

/**
 * token过滤器 验证token有效性
 *
 * @author
 */
@Component("jwtAuthorizationTokenFilter")
public class JwtAuthorizationTokenFilter extends OncePerRequestFilter {

    private static final Logger log = LoggerFactory.getLogger(JwtAuthorizationTokenFilter.class);

    private JwtUserDetailsService jwtUserDetailsService;
    private final JwtTokenUtils jwtTokenUtils;

    public JwtAuthorizationTokenFilter(JwtUserDetailsService jwtUserDetailsService, JwtTokenUtils jwtTokenUtils) {
        this.jwtUserDetailsService = jwtUserDetailsService;
        this.jwtTokenUtils = jwtTokenUtils;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        final String url = request.getRequestURI();
        final String InternalServer = request.getHeader(Constants.CUSTOM_HEADERS_SERVER_TYPE);
        JwtUser jwtUser = jwtTokenUtils.getJwtUser(request);
        log.info("JwtAuthorizationTokenFilter.doFilterInternal(), 当前用户：{}", StringUtils.isNotNull(jwtUser) ? jwtUser.getUsername() : "");

        // 内部服务不拦截
        if("InternalServer".equals(InternalServer)) {
            if (StringUtils.isNull(jwtUser)) {
                // jwtUser 用户为空，取默认值
                jwtUser = (JwtUser) jwtUserDetailsService.loadUserByUsername("hacker");
                if (StringUtils.isNotNull(jwtUser)) {
                    jwtUser.setToken(Constants.CUSTOM_DEFAULT_TOKEN);
                    jwtTokenUtils.setUserAgent(jwtUser);
                    jwtTokenUtils.refreshToken(jwtUser);
                }
            }
            log.info("JwtAuthorizationTokenFilter.doFilterInternal(), 内部服务当前用户：{}", StringUtils.isNotNull(jwtUser) ? jwtUser.getUsername() : "");

            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities());
            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            ActiveUserUtils.setActiveUserMap(SecurityUtils.getJwtUser().getUser());

            chain.doFilter(request, response);
            return;
        }

        if (StringUtils.isNotNull(jwtUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) {
            log.info("JwtAuthorizationTokenFilter.doFilterInternal(), url：{}", url);

            jwtTokenUtils.verifyToken(jwtUser);
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(jwtUser, null, jwtUser.getAuthorities());
            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            ActiveUserUtils.setActiveUserMap(SecurityUtils.getJwtUser().getUser());
        }
        
        chain.doFilter(request, response);
    }

}
