package cn.wisenergy.web.shiro.filter;

import cn.wisenergy.common.constant.RedisConsts;
import cn.wisenergy.common.enums.RespCodeEnum;
import cn.wisenergy.model.app.AccountInfo;
import cn.wisenergy.model.app.User;
import cn.wisenergy.service.app.UserService;
import cn.wisenergy.web.config.JwtConfig;
import cn.wisenergy.web.shiro.AuthToken;
import cn.wisenergy.web.shiro.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.*;
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.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 认证
 *
 * @author lut
 */
@Slf4j
@Component
public class AuthRealm extends AuthorizingRealm {

    @Autowired
    private UserService sysUserService;
    @Autowired
    private UserService authUserService;
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private JwtConfig jwtConfig;
    @Resource
    RedisTemplate<String, Object> redisTemplate;

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

    /**
     * 授权(验证权限时调用)
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        AccountInfo user = (AccountInfo) principals.getPrimaryPrincipal();
        String userId = user.getId().toString();
        //用户权限列表
//        Set<String> permsSet = sysUserService.queryAllPerms(userId);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//        info.setStringPermissions(permsSet);
        return info;
    }

    /**
     * 认证(登录时调用)
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 获取token
        String accessToken = (String) token.getPrincipal();
        User userEntity = null;
        Boolean refreshFlag = false;
        // 解析token
        Claims claims = jwtUtil.getClaimsFromToken(accessToken);
        // 从token中获取用户
        userEntity = jwtUtil.getUserFromToken(claims);
        // 获取redis Key
        String redisKey = RedisConsts.JWT_ACCESS_TOKEN + accessToken;
        // 从redis中获取token
        String redisToken = (String) redisTemplate.opsForValue().get(redisKey);
      /*  try {
            if (redisToken != null) {
                //这里刷新token 是否过期，如果过期需要更新token
                if (jwtUtil.isTokenExpired(claims)) {
                    // 重新签发token
                    String refreshToken = jwtUtil.generateToken(userEntity);
                    // 将新token存入Redis中
                    redisTemplate.opsForValue().set(RedisConsts.JWT_ACCESS_TOKEN + refreshToken, refreshToken, jwtConfig.getExpire() + 60 * 60);
                    HttpServletResponse resp = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
                    resp.setHeader("refresh-token", accessToken);
                    refreshFlag = true;
                }
            } else {
                throw new IncorrectCredentialsException(RespCodeEnum.NO_AUTH_REQUEST.getMsg());
            }
        } catch (ExpiredJwtException e) {
            // token解析异常
            log.error("token解析异常，ex={}", e.getMessage(), e);
            throw new IncorrectCredentialsException(RespCodeEnum.TOKEN_IS_NOT_TIMEOUT.getMsg());
        }*/
        //查询用户信息
        User user = authUserService.getByUserId(userEntity.getUserId());
        // 判断请求token与redis中是否相同，如果token被刷新，则不判断
        if (!refreshFlag && !StringUtils.equals(accessToken, redisToken)) {
            throw new IncorrectCredentialsException(RespCodeEnum.NO_AUTH_REQUEST.getMsg());
        }
        // 账号不存在
        if (user == null) {
            throw new UnknownAccountException("账号不存在");
        }
        // 密码错误
//        if (!password.equals(user.getPassword())) {
//            throw new IncorrectCredentialsException("账号或密码不正确");
//        }
        //账号锁定
//        if (user.getStatus() == 2) {
//            throw new LockedAccountException("账号已被锁定,请联系管理员");
//        }
        if (refreshFlag) {
            // 重置Redis中token过期时间，如果token被刷新，则不进行重置
            redisTemplate.opsForValue().set(redisKey, accessToken, jwtConfig.getExpire() + 60 * 60);
        }
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, accessToken, getName());
        return info;
    }

}
