package com.bootdo.common.token;

import com.bootdo.common.constant.Constants;
import com.bootdo.common.utils.*;
import com.bootdo.system.domain.UserDO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;


/**
 * @author 宋显哲
 * @version 1.0.0 创建于 2018/1/18
 **/
@Component
public final class TokenUtil {
    @Resource
    private RedisUtil redisUtil;
    @Value("${server.session-timeout}")
    private long tomcatTimeout;

    /**
     * 从缓存中取校验当前用户是否登录,key的格式为：online:{username}
     *
     * @param username 账号
     * @return 返回1，如果返回空则表示该用户不在线
     * @throws Exception 异常信息
     */
    public String getLoginUser(String username) throws Exception {
        String value = (String)redisUtil.hget(Constants.ONLINE_USER, username);
        if(ObjectUtils.isEmpty(value)){
            return null;
        } else {
            return value;
        }
    }

    /**
     * @param username 账号
     * @param token    token
     * @throws Exception 异常信息
     */
    public void saveLoginUser(String username, String token,String ip, long currTime,String sysFlag) throws Exception {
        redisUtil.hset(Constants.ONLINE_USER, username, token + "_" + ip + "_" + currTime + "_" + sysFlag, tomcatTimeout);
    }
    /**
     * 从请求中读取Token
     *
     * @param tokenStr
     * @return 如果没有token，则返回null，否则返回Token对象
     * @throws Exception 异常信息
     */
    public Token getToken(String tokenStr) throws Exception {
        if (StringUtils.isEmpty(tokenStr)) {
            return null;
        }
        return parseTokenStr(tokenStr);
    }

    /**
     * 解析Token 字符串
     *
     * @param tokenStr
     * @return
     * @throws Exception
     */
    private Token parseTokenStr(String tokenStr) throws Exception {
        if (StringUtils.isEmpty(tokenStr)) {
            throw new Exception("令牌为空！");
        }
        String tokenJsonStr = AesUtil.decrypt(tokenStr,
                CommonConfUtil.getConf("aes.key"),
                CommonConfUtil.getConf("aes.iv"));
        return JsonUtil.fromJson(tokenJsonStr, Token.class);
    }

    /**
     * 对Token对象进行签名，并且生成token对象
     * @param token token对象
     * @return 返回签名后的token字符串
     * @throws Exception 异常信息
     */
    private String createTokenString(Token token) throws Exception {
        String sig = RsaUtil.signature(CommonConfUtil.getConf("sig.priKey"), token.getPayload().toString());
        token.setSig(sig);
        return AesUtil.encrypt(JsonUtil.toJson(token), CommonConfUtil.getConf("aes.key"), CommonConfUtil.getConf("aes.iv"));
    }

    /**
     * 校验token是否被篡改
     *
     * @param token token对象
     * @return 被篡改则返回false，否则返回true.
     */
    public boolean verifyToken(Token token) throws Exception {
        return RsaUtil.verifySig(CommonConfUtil.getConf("sig.pubKey"), token.getPayload().toString(), token.getSig());
    }


    public static void main(String[] args) throws Exception {
        Token token = new TokenUtil().parseTokenStr("VcXRinlhXTEJft64IYy/6E2ISRCEz78HjDKXqOKruF9UsibFK15dz1Y4NbiRBuDuKy5/aeDFSMk/dJ51wC7kNl6D4emBtr67NS9D4i6zRwz1IRMd13BWJO/+RbxqEVFisr/9fXI9Btsonka9zQDVAiIwgkqb+th0SLxu2XJmTxRhv2/5QB6y9gYpU8B83P8Sped1lBLU6iqLF+igsL8ma7CZDOsYc3/0/Nys56fDxMBn0vBbdOWk15p1cD/Ark2qc2nqPleSQfsKIbpS0LnfGhEizatZI1oI+i4+H7kstsxOzez37SpU9iuU8ApF7eTbha5ojH7fzqybqoU2TWSxBCW363X3j9iR5VDA89J2wrotv9AQo4Ya+tNayxpxUIqqi2HsH4FudVPucdajjvmDYokDg7HAwmfsT0TW1xqMxTFg/K6VGegO7O7OJs7nXbQjldNCnS9qadCZzXuKu90kCy0dz70l7RDozSJpNbTcSrTcRLpPPN+ytuezUEYmjQlm");
        System.out.println(JsonUtil.toJson(token));
    }
}
