package org.ccpit.base.utils;

import org.ccpit.base.role.Role;
import org.ccpit.base.role.RoleService;
import org.ccpit.base.role.RoleUrl;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Repository;

import java.util.*;

/**
 * url-role 缓存映射表
 * 存储rul-role的映射
 * Created by sqp on 2015/9/29.
 */
@Repository
public class UrlRolesMapper implements ApplicationContextAware {
    //状态码  -1：不可用  0：未初始化   1：可用
    private static int status = 0;
    //存储器
    private static final Map<String, Set<Role>> MAP = new HashMap<String, Set<Role>>();
    //spring上下文根
    private static ApplicationContext ac;

    /**
     * 从数据库中重载数据
     */
    public void reload() {
        MAP.clear();
        Collections.synchronizedMap(MAP);
        status = -1;
        List<Role> roleList = ac.getBean(RoleService.class).getAllRoles();
        for (Role role : roleList) {
            List<RoleUrl> urls = role.getUrlPerfixs();
            for (RoleUrl roleUrl : urls) {
                String url = roleUrl.getUrl();
                if (MAP.containsKey(url))
                    MAP.get(url).add(role);
                else {
                    Set<Role> set = new HashSet<Role>();
                    MAP.put(url, set);
                    set.add(role);
                }
            }
        }
        status = 1;
    }

    /**
     * 根据url获取对应的roles
     *
     * @param url
     * @return
     */
    public Set<Role> getRoles(String url) {
        if (status == 1)
            return MAP.get(url);
        if (status == -1) {
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return getRoles(url);
        }

        reload();
        return getRoles(url);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ac = applicationContext;
    }
}
