package com.liangjian.dataplatform.member.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.liangjian.dataplatform.member.entity.token.JwtToken;
import com.liangjian.dataplatform.member.entity.token.JwtTokenObject;

import java.util.Date;
import java.util.Map;
import java.util.Optional;

/**
 * @Author: 黄子奇
 * @Date: 2019/10/8 16:58
 */
public class JwtUtil {

    public static boolean verify(String jwt,String secret) {
        try {
            //使用HMAC256加密算法加密签名，后续可改
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT _jwt = verifier.verify(jwt);
            return true;
        } catch (JWTVerificationException ex) {
            return false;
        }
    }

    /**
     * 获取payload的对象
     * @param jwtToken
     * @return
     */
    public static JwtToken getPayload(String jwtToken) {
        DecodedJWT jwt = JWT.decode(jwtToken);
        Long roleid = jwt.getClaim("roleid").asLong();
        String rolename = jwt.getClaim("rolename").asString();
        String username = jwt.getClaim("username").asString();
        Long userid = jwt.getClaim("userid").asLong();
        String CurrentEmployeeID = jwt.getClaim("CurrentEmployeeID").asString();
        String CurrentDeptID = jwt.getClaim("CurrentDeptID").asString();
        Date CurrentUserLastLoginTime = jwt.getClaim("CurrentUserLastLoginTime").asDate();
        Map<String,Object> permission = jwt.getClaim("permission").asMap();
        String wxresponse = jwt.getClaim("wxresponse").asString();

        JwtToken token = new JwtToken();
        token.setRoleid(roleid);
        token.setRolename(rolename);
        token.setUsername(username);
        token.setUserid(userid);
        token.setCurrentEmployeeID(CurrentEmployeeID);
        token.setCurrentDeptID(CurrentDeptID);
        token.setCurrentUserLastLoginTime(CurrentUserLastLoginTime);
        token.setPermission(permission);
        token.setWxresponse(wxresponse);
        return token;
    }

    public static <T> Optional<JwtTokenObject<T>> getPlayload(String jwtToken, Class<T> clazz) {
        DecodedJWT jwt = JWT.decode(jwtToken);
        String objectjs = jwt.getClaim("object").asString();
        Long signTime = jwt.getClaim("signTime").asLong();
        String remark = jwt.getClaim("remark").asString();

        ObjectMapper mapper = new ObjectMapper();
        ObjectReader reader = mapper.readerFor(clazz);
        try {
            T object = reader.readValue(objectjs);
            JwtTokenObject<T> tokenObject = new JwtTokenObject<>();
            tokenObject.setObject(object);
            tokenObject.setSignTime(signTime);
            tokenObject.setRemark(remark);
            return Optional.of(tokenObject);
        } catch (Exception ex) {
            ex.printStackTrace();
            return Optional.empty();
        }
    }
}
