package com.lightinit.hsdataplatformresdir.spring;

import com.lightinit.hsdataplatformresdir.entity.Admin;
import com.lightinit.hsdataplatformresdir.entity.SentryRoleAction;
import com.lightinit.hsdataplatformresdir.model.admin.LoginUser;
import com.lightinit.hsdataplatformresdir.service.IAdminService;
import com.lightinit.hsdataplatformresdir.service.IRoleService;
import com.lightinit.hsdataplatformresdir.service.IShiroPermissionsService;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.authz.permission.WildcardPermission;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by Mr.Yao on 2017/3/22.
 */
public class SentryRealm extends AuthorizingRealm {
    @Autowired
    private IAdminService adminService;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private IShiroPermissionsService shiroPermissionsService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals){
        /*String username = (String)principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        // 权限控制
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        if (session == null){
            return null;
        }
        LoginUser loginUser = (LoginUser) session.getAttribute(LoginUser.SESSION_KEY_LOGIN_USER);
        if (loginUser == null){
            return null;
        }
        Set<String> roles = new HashSet<String>(loginUser.getRoles());
        boolean isSuperAdmin = roles.stream().anyMatch(q -> q.equalsIgnoreCase("admin"));
        authorizationInfo.setRoles(roles);
        Set<Permission> actions = new HashSet<Permission>();
        if(isSuperAdmin==false) {
            List<SentryRoleAction> sentryRoleActionList = shiroPermissionsService.selectSentryRoleAction(new ArrayList<String>(roles));
            for (SentryRoleAction roleModuleAction : sentryRoleActionList) {
                if (StringUtils.isEmpty(roleModuleAction.getMenucode()) || StringUtils.isEmpty(roleModuleAction.getActioncode())){
                    continue;
                }
                Permission wildcardPermission = new WildcardPermission(MessageFormat.format("{0}:{1}", roleModuleAction.getMenucode(), roleModuleAction.getActioncode()));
                if (actions.contains(wildcardPermission) == false) {
                    actions.add(wildcardPermission);
                }
            }
        }else{
            Permission wildcardPermission = new WildcardPermission("*:*");
            actions.add(wildcardPermission);
        }
        authorizationInfo.setObjectPermissions(actions);
        return authorizationInfo;*/

        String username = (String)principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        // 暂时不加权限
        Set<Permission> actions = new HashSet<>();
        Permission wildcardPermission = new WildcardPermission("*:*");
        actions.add(wildcardPermission);
        authorizationInfo.setObjectPermissions(actions);
        return authorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String)token.getPrincipal();
        // TODO: 2017/4/7 验证当前用户的是否合法
        Admin adminEntity=adminService.SelectOne(username);
        if(adminEntity==null)
            return null;
//        adminEntity.setUsername("admin");
//        adminEntity.setId(1L);
//        String salt = new SecureRandomNumberGenerator().nextBytes().toHex();
//        String password_cipherText= new Md5Hash("admin",username+salt,3).toHex();
//        adminEntity.setPassword(password_cipherText);


        //交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配，如果觉得人家的不好可以自定义实现
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                adminEntity.getUsername(), //用户名
                adminEntity.getPassword(), //密码
                ByteSource.Util.bytes(username+adminEntity.getSalt()),//salt=username+salt
                getName()  //realm name
        );
        return authenticationInfo;
    }

    @Override
    public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        super.clearCachedAuthorizationInfo(principals);
    }

    @Override
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        super.clearCachedAuthenticationInfo(principals);
    }

    @Override
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }

    public void clearAllCachedAuthorizationInfo() {
        getAuthorizationCache().clear();
    }

    public void clearAllCachedAuthenticationInfo() {
        getAuthenticationCache().clear();
    }

    public void clearAllCache() {
        clearAllCachedAuthenticationInfo();
        clearAllCachedAuthorizationInfo();
    }
}
