package com.ho.user.config.shiro;


import com.ho.common.tools.constant.RedisKeyConstant;
import com.ho.common.tools.entity.UserDetailRespVO;
import com.ho.common.tools.util.RedisCommon;
import com.ho.user.service.PermissionService;
import com.ho.user.service.RoleService;
import com.ho.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

import java.util.HashSet;
import java.util.List;

/**
 * @ClassName: CustomRealm
 * TODO:类文件简单描述
 * @Author:
 * @CreateDate: 2019/9/6 18:02
 * @UpdateUser:
 * @UpdateDate: 2019/9/6 18:02
 * @Version: 0.0.1
 */
@Slf4j
public class CustomRealm extends AuthorizingRealm {
    @Autowired
    @Lazy
    private RedisCommon redisCommon;

    @Autowired
    @Lazy
    private PermissionService permissionService;

    @Autowired
    @Lazy
    private RoleService roleService;

    @Autowired
    @Lazy
    UserService userService;


    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof CustomPasswordToken;
    }

    //认知
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        CustomPasswordToken token = (CustomPasswordToken) authenticationToken;
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(token.getPrincipal(), token.getPrincipal(), getName());
        return simpleAuthenticationInfo;
    }

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        String accessToken = (String) SecurityUtils.getSubject().getPrincipal();
        String userTokenKey = RedisKeyConstant.User.TOKEN + accessToken;

        log.info("doGetAuthorizationInfo, accessToken:{}", accessToken);
        UserDetailRespVO user = (UserDetailRespVO) redisCommon.get(userTokenKey);
        if (user != null) {
            //List<String> roleNames = user.getRoleNames();
            List<String> roleNames = user.getRoles();
            if (roleNames != null && !roleNames.isEmpty()) {
                //authorizationInfo.addRoles(roleService.getRoleNames(userId));
                //直接把结果集放进去,避免再次执行一遍sql
                authorizationInfo.addRoles(roleNames);
            }
            if (user.getPowerList() != null) {
                authorizationInfo.setStringPermissions(new HashSet<>(user.getPowerList()));
            }
        } else {
            List<String> roleNames = roleService.getRoleNames(user.getUserId());
            if (roleNames != null && !roleNames.isEmpty()) {
                //直接把结果集放进去,避免再次执行一遍sql
                authorizationInfo.addRoles(roleNames);
            }
            authorizationInfo.setStringPermissions(permissionService.getPermissionsByUserId(user.getUserId()));
        }

        return authorizationInfo;
    }

}
