package com.njcn.shiro.token;



import com.njcn.pojo.user.AppUser;
import com.njcn.sso.pojo.user.User;
import com.njcn.shiro.realm.DataRealm;
import com.njcn.shiro.session.UserSessionManager;
import com.njcn.utils.SpringContextUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.SimplePrincipalCollection;

import java.util.List;


public class TokenManager {

	//用户登录管理
	public static final DataRealm dataRealm = SpringContextUtil.getBean("dataRealm",DataRealm.class);

	//用户session管理
	public static final UserSessionManager userSessionManager = SpringContextUtil.getBean("userSessionManager",UserSessionManager.class);


	/**
	 * 登录
	 */
	public static User login(String username,String type,String password, String ip,String item){
		ShiroToken token = new ShiroToken(username, password);
		token.setIp(ip);
		token.setItem(item);
		token.setType(type);
		SecurityUtils.getSubject().login(token);
		return getToken();
	}

	public static AppUser appLogin(String phone, String type, String key, String devCode, String item) {
		ShiroToken token = new ShiroToken(phone, key);
		token.setItem(item);
		token.setType(type);
		token.setDevCode(devCode);
		SecurityUtils.getSubject().login(token);
		return getAppToken();
	}

	/**
	 * 获取当前登录的用户User对象
	 */
	public static User getToken(){
		User token = (User) SecurityUtils.getSubject().getPrincipal();
		return token ;
	}

	/**
	 * 获取当前登录的用户User对象
	 */
	public static AppUser getAppToken(){
		AppUser token = (AppUser) SecurityUtils.getSubject().getPrincipal();
		return token ;
	}


	/**
	 * 获取当前用户的Session
	 */
	public static Session getSession(){
		return SecurityUtils.getSubject().getSession();
	}
	/**
	 * 获取当前用户NAME
	 */
	public static String getNickname(){
		return getToken().getName();
	}

	/**
	 * 获取当前用户ID
	 */
	public static String getUserId(){
		return getToken()==null?null:getToken().getUserIndex();
	}

	/**
	 * 把值放入到当前登录用户的Session里
	 * @param key 键
	 * @param value 值
	 */
	public static void setVal2Session(Object key ,Object value){
		getSession().setAttribute(key, value);
	}


	/**
	 * 从当前登录用户的Session里取值
	 * @param key 键
	 */
	public static Object getVal2Session(Object key){
		return getSession().getAttribute(key);
	}




	/**
	 * 判断是否登录
	 */
	public static boolean isLogin() {
		return null != SecurityUtils.getSubject().getPrincipal();
	}
	/**
	 * 退出登录
	 */
	public static void logout() {
		SecurityUtils.getSubject().logout();
	}

	/**
	 * 清空当前用户权限信息。
	 * 目的：为了在判断权限的时候，再次会再次 <code>doGetAuthorizationInfo(...)  </code>方法。
	 * ps：	当然你可以手动调用  <code> doGetAuthorizationInfo(...)  </code>方法。
	 * 		这里只是说明下这个逻辑，当你清空了权限，<code> doGetAuthorizationInfo(...)  </code>就会被再次调用。
	 */
	public static void clearNowUserAuth(){
		/**
		 * 这里需要获取到shrio.xml 配置文件中，对Realm的实例化对象。才能调用到 Realm 父类的方法。
		 */
		/**
		 * 获取当前系统的Realm的实例化对象，方法一（通过 @link org.apache.shiro.web.mgt.DefaultWebSecurityManager 或者它的实现子类的{Collection<Realm> getRealms()}方法获取）。
		 * 获取到的时候是一个集合。Collection<Realm>
		 RealmSecurityManager securityManager =
		 (RealmSecurityManager) SecurityUtils.getSecurityManager();
		 Pqs9000realm realm = (Pqs9000realm)securityManager.getRealms().iterator().next();
		 */
		/**
		 * 方法二、通过ApplicationContext 从Spring容器里获取实列化对象。
		 */
		dataRealm.clearCachedAuthorizationInfo();
		/**
		 * 当然还有很多直接或者间接的方法，此处不纠结。
		 */
	}

	public static String getSysType(){
		return (String) getSession().getAttribute("sysType");
	}


	/**
	 * 根据UserIds 	清空权限信息。
	 */
	public static void clearUserAuthByUserId(String...userIds){

		if(null == userIds || userIds.length == 0)	return ;
		List<SimplePrincipalCollection> result = userSessionManager.getSimplePrincipalCollectionByUserId(userIds);

		for (SimplePrincipalCollection simplePrincipalCollection : result) {
			dataRealm.clearCachedAuthorizationInfo(simplePrincipalCollection);
		}
	}


	/**
	 * 方法重载
	 * @param userIds 根据用户索引清除用户当前的权限信息
	 */
	public static void clearUserAuthByUserId(List<String> userIds) {
		if(null == userIds || userIds.size() == 0){
			return ;
		}
		clearUserAuthByUserId(userIds.toArray(new String[0]));
	}



}
