package com.koobietech.eas.security.filter;

import com.koobietech.eas.common.exception.EasException;
import com.koobietech.eas.common.pojo.JwtUserDto;
import com.koobietech.eas.common.utils.JwtManager;
import com.koobietech.eas.dao.adminLoginPojo.Permission;
import com.koobietech.eas.dao.adminLoginPojo.UserDetail;
import com.koobietech.eas.service.LoginRedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class EasSecurityFilter extends OncePerRequestFilter {

    private static final Logger logger = LoggerFactory.getLogger(EasSecurityFilter.class);

    @Resource
    private LoginRedisService loginRedisService;

    @Resource
    JwtManager jwtManager;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        //从请求里面拿到token
        String token = request.getHeader("Authorization");
        //判断token是否存在
        if (StringUtils.hasText(token)) {
            //解析token成JwtUserDto
            JwtUserDto jwtUserDto = null;
            try {
                //过滤器 允许 Token 不正确, 后面Security 会拦截处理
                jwtUserDto = jwtManager.decodeJwt(token);
            } catch ( EasException e) {
                logger.debug(e.getMessage());
            }
            if ( Objects.nonNull(jwtUserDto) ) {
                //判断token是否有效
                UserDetail userDetail = null;
                try {
                    userDetail = loginRedisService.checkToken(jwtUserDto);
                } catch ( EasException e) {
                    logger.debug(e.getMessage());
                }

                // 如果获取到了有效的用户对象
                if (Objects.nonNull(userDetail)) {
                    // 获取当前的 SecurityContext 对象，用于保存当前用户的安全上下文信息
                    SecurityContext context = SecurityContextHolder.getContext();

                    // 获取用户的权限列表
                    List<Permission> permission = userDetail.getPermissions();

                    // 创建一个 ArrayList 集合，用于存储用户权限对应的 SimpleGrantedAuthority 权限对象
                    ArrayList<SimpleGrantedAuthority> objects = new ArrayList<>();

                    // 遍历用户的权限列表
                    for (Permission adminPermission : permission) {
                        // 创建一个 SimpleGrantedAuthority 权限对象，并添加到集合中
                        SimpleGrantedAuthority authority = new SimpleGrantedAuthority(adminPermission.getDescription());
                        objects.add(authority);
                    }

                    // 使用用户的用户名、空凭证参数和权限对象集合创建一个 UsernamePasswordAuthenticationToken 身份验证令牌
                    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetail.getUsername(), null, objects);

                    // 将身份验证令牌设置到当前的 SecurityContext 中
                    context.setAuthentication(authenticationToken);
                }
            }
        }
        filterChain.doFilter(request, response);
    }

}
