package com.cftech.sys.security;

import com.cftech.core.sql.Conds;
import com.cftech.core.util.SpringContextHolder;
import com.cftech.sys.model.Permission;
import com.cftech.sys.model.Role;
import com.cftech.sys.model.User;
import com.cftech.sys.service.PermissionService;
import com.cftech.sys.service.RoleService;
import com.cftech.sys.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户身份验证,授权 Realm 组件
 * 
 * @author lisw
 * @since 2016年8月17日 上午11:35:28
 **/
/*@Component(value = "securityRealm")*/
public class SecurityRealm extends AuthorizingRealm {
 
    //@Resource
    private UserService userService;

    //@Resource
    private RoleService roleService;

    //@Resource
    private PermissionService permissionService;

    /**
     * 权限检查
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    	permissionService = SpringContextHolder.getBean("permissionServiceImpl");
    	userService = SpringContextHolder.getBean("userServiceImpl");
    	roleService = SpringContextHolder.getBean("roleServiceImpl");
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        Principal username = (Principal)  principals.getPrimaryPrincipal();
        if("1".equals(username.getId().toString()))
        {
        	  final List<Permission> permissions = permissionService.getAllPermission();
              for (Permission permission : permissions) {
                  authorizationInfo.addStringPermission(permission.getPermissionSign());
              }
              final List<Role> roles = roleService.selectAll(null);
              for (Role role: roles) {
				  authorizationInfo.addRole(role.getRoleSign());
			  }
        	 return authorizationInfo;
        }



        Conds conds = new Conds();
        conds.equal("username", username.getLoginName());
		conds.equal("delflag",0);
        final User user = userService.fetchSearchByConds(conds);
        String roles =  user.getRoles();
		roles = roles.replace("'","");
       if(StringUtils.isNotBlank(roles))
       {
    	   List<Role> roleInfos = roleService.getRoleByIds(roles);
    	   if(roleInfos!=null)
    	   {
    		   for (Role role : roleInfos) 
        	   {
                   authorizationInfo.addRole(role.getRoleSign());
                   final List<Permission> permissions = permissionService.selectPermissionsByRoleId(role.getId());
                   for (Permission permission : permissions) {
                       authorizationInfo.addStringPermission(permission.getPermissionSign());
                   }
               }  
    	   }
       }
       
        return authorizationInfo;
    }

    /**
     * 登录验证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = String.valueOf(token.getPrincipal());
        String password = new String((char[]) token.getCredentials());
    	userService = SpringContextHolder.getBean("userServiceImpl");
        // 通过数据库进行验证
    	Conds conds = new Conds();
    	conds.equal("username",username);
    	conds.equal("password",password);
    	conds.equal("delflag", 0);
		conds.equal("state", 0);
    	User authentication = userService.fetchSearchByConds(conds);
        if (authentication == null) {
            throw new AuthenticationException("用户名或密码错误");
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(new Principal(authentication), password, getName());
        return authenticationInfo;
    }
    
    
	/**
	 * 授权用户信息
	 */
	public static class Principal implements Serializable {

		private static final long serialVersionUID = 1L;
		
		private Long id;
		private String loginName;
		private String name;
		private Map<String, Object> cacheMap;

		public Principal(User user) {
			this.id = user.getId();
			this.loginName = user.getUsername();
			this.name = user.getDescription();
		}

		public Long getId() {
			return id;
		}

		public String getLoginName() {
			return loginName;
		}

		public String getName() {
			return name;
		}

		public Map<String, Object> getCacheMap() {
			if (cacheMap==null){
				cacheMap = new HashMap<String, Object>();
			}
			return cacheMap;
		}

	}

}
