package cn.com.capcloud.core.system.security;

import cn.com.capcloud.core.system.role.RoleService;
import cn.com.capcloud.core.system.user.User;
import cn.com.capcloud.core.system.user.UserService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;

@Component
public class UrlFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
    Logger logger = LogManager.getLogger();
    @Value("${server.servlet.context-path}")
    private  String contextPath;
    @Resource
    private AntPathMatcher antPathMatcher;
    @Resource
    private RoleService roleService;
    @Resource
    private UserService userService;
    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        String requestUrl = ((FilterInvocation) object).getRequest().getRequestURI();
        //判断如果是websocketURL就放行（注：websocket此时也是登录状态了，token是在url传进来）
        if(antPathMatcher.match(contextPath+"/ws/websocket/**", requestUrl)){
            return null;
        }
        // 判断访问的URL是否是NoLogin就能访问的URL
        // 如：登录，获取签名和验证码这些资源是不需要登录的
        List<Map<String,Object>> listNoSessionURL=roleService.getNoLoginURL();
        for (int i = 0; i < listNoSessionURL.size(); i++) {
            if (antPathMatcher.match(contextPath+listNoSessionURL.get(i).get("url_path"), requestUrl)) {
                requestUrl=requestUrl.replace(contextPath,"");
                return null;
            }
        }
        // 访问的URL不是NoLoginURL
        // 判断是不是登录就能的访问URL
        List<Map<String,Object>> listNotRolesURL=roleService.getNotRoleURL();
        if(listNotRolesURL!=null){
            for (int i = 0; i < listNotRolesURL.size(); i++) {
                if (antPathMatcher.match(contextPath+listNotRolesURL.get(i).get("url_path"), requestUrl)) {
                    logger.info("请求"+requestUrl+" 资源需要登录才能访问");
                    return SecurityConfig.createList("ROLE_LOGIN");
                }
            }
        }
        // 访问的URL不是NoLoginURL也不是NotRoleURL
        // 取出该URL对应的角色
        User user=userService.getUser(((FilterInvocation) object).getRequest());
        List<Map<String,Object>> listMenu=roleService.getMenuByLoginUserName(user.getUserLoginName());
        if(listMenu!=null){
            for (int i = 0; i < listMenu.size(); i++) {
                if (antPathMatcher.match(contextPath+listMenu.get(i).get("menu_url"), requestUrl)) {
                    List<Map<String,Object>> listRole=roleService.getRolesIdByMenuId(String.valueOf(listMenu.get(i).get("menu_id")));
                    String[] str = new String[listRole.size()];
                    for (int j = 0; j < listRole.size(); j++) {
                        str[j] = "ROLE_"+listRole.get(j).get("role_id");
                    }
                    return SecurityConfig.createList(str);
                }
            }
        }
        //logger.warn("请求"+requestUrl+" 既不是NoLogin资源，也不是角色资源。");//后端可以返回无效资源或跳到首页，还没实现
        //return SecurityConfig.createList("ROLE_NO");//还没实现
        return SecurityConfig.createList("ROLE_LOGIN");//权限表还没做，先都返回登录就能请求
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return false;
    }
    @Bean
    public AntPathMatcher antPathMatcher() {
        return new AntPathMatcher();
    }
}
