package com.nbclass.shiro;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.nbclass.holder.SpringContextHolder;
import com.nbclass.system.model.Permission;
import com.nbclass.system.service.PermissionService;
import com.nbclass.util.CoreConst;

/**
 * 
 * @author Leon
 * @datetime 2019年4月1日 下午2:47:53
 */
@Service
public class ShiroService {
	
    @Autowired
    private PermissionService permissionService;
    
    /**
     * 初始化加载权限
     * @return
     */
    public Map<String, String> loadFilterChainDefinitions() {
        // 权限控制map.从数据库获取
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        
        filterChainDefinitionMap.put("/register", "anon");
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/error/**", "anon");
        filterChainDefinitionMap.put("/kickout", "anon");
        /*filterChainDefinitionMap.put("/logout", "logout");*/
        filterChainDefinitionMap.put("/verificationCode", "anon");	// 登录验证码
        filterChainDefinitionMap.put("/qywx/qrLogin", "anon"); 		// 企业微信登录页面
        
        // 前端接口放行
        filterChainDefinitionMap.put("/front/api/**", "anon"); // 前端接口
        filterChainDefinitionMap.put("/", "anon");	// 网站首页
        filterChainDefinitionMap.put("/caseType/**", "anon");	// 数据字典
        filterChainDefinitionMap.put("/wx/**", "anon");	// wx接口
        filterChainDefinitionMap.put("/comment/**", "anon");	// wx接口
        filterChainDefinitionMap.put("/console/content/saveScore", "anon");	//

        filterChainDefinitionMap.put("/mobile/*.html", "wxWebOAuth"); // 移动端页面授权拦截
        
        // 静态资源按目录排除
        filterChainDefinitionMap.put("/css/**","anon");
        filterChainDefinitionMap.put("/js/**","anon");
        filterChainDefinitionMap.put("/img/**","anon");
        filterChainDefinitionMap.put("/libs/**","anon");
        // 静态资源按后缀排除
        filterChainDefinitionMap.put("/**/*.ico", "anon");
        filterChainDefinitionMap.put("/**/*.htm", "anon");
        filterChainDefinitionMap.put("/**/*.html", "anon");
        filterChainDefinitionMap.put("/**/*.css", "anon");
        filterChainDefinitionMap.put("/**/*.js", "anon");
        filterChainDefinitionMap.put("/**/*.jpg", "anon");
        filterChainDefinitionMap.put("/**/*.png", "anon");
        filterChainDefinitionMap.put("/**/*.gif", "anon");
        filterChainDefinitionMap.put("/**/*.webp", "anon");
        filterChainDefinitionMap.put("/**/*.ttf", "anon");
        filterChainDefinitionMap.put("/**/*.woff", "anon");
        filterChainDefinitionMap.put("/**/*.woff2", "anon");
        filterChainDefinitionMap.put("/**/*.mp3", "anon");
        filterChainDefinitionMap.put("/**/*.mp4", "anon");
        filterChainDefinitionMap.put("/**/*.txt", "anon");
        
        
        List<Permission> permissionList = permissionService.selectAll(CoreConst.STATUS_VALID);
        for(Permission permission : permissionList){
            if (StringUtils.isNotBlank(permission.getUrl())&& StringUtils.isNotBlank(permission.getPerms())) {
                String perm = "perms[" + permission.getPerms()+ "]";
                filterChainDefinitionMap.put(permission.getUrl(),perm+",kickout");
            }
        }
        
        filterChainDefinitionMap.put("/**", "user,kickout");
        
        return filterChainDefinitionMap;
    }

    /**
     * 添加/修改/删除 后 重新加载权限
     */
    public void updatePermission() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = SpringContextHolder.getBean(ShiroFilterFactoryBean.class);
        synchronized (shiroFilterFactoryBean) {
            AbstractShiroFilter shiroFilter = null;
            try {
                shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject();
            } catch (Exception e) {
                throw new RuntimeException("get ShiroFilter from shiroFilterFactoryBean error!");
            }

            PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter
                    .getFilterChainResolver();
            DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver
                    .getFilterChainManager();

            // 清空老的权限控制
            manager.getFilterChains().clear();

            shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();
            shiroFilterFactoryBean.setFilterChainDefinitionMap(loadFilterChainDefinitions());
            // 重新构建生成
            Map<String, String> chains = shiroFilterFactoryBean.getFilterChainDefinitionMap();
            for (Map.Entry<String, String> entry : chains.entrySet()) {
                String url = entry.getKey();
                String chainDefinition = entry.getValue().trim().replace(" ", "");
                manager.createChain(url, chainDefinition);
            }
        }
    }
}
