package com.fdkanfang.web.shiro;

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.log4j.Log4j2;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Log4j2
public class JWTUtil {

    // 过期时间24小时
    private static final long EXPIRE_TIME = 24*60*60*1000;


    /**
     * 校验token是否正确
     * @param token 密钥
     * @param secret 用户的密码
     * @return 是否正确
     */
    public static boolean verify(String token, String userName, String secret) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withClaim("userName", userName)
                    .build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception e) {
            e.getMessage();
            log.error(e.getMessage());
            return false;
        }
    }




    /**
     * 获得token中的信息无需secret解密也能获得
     * @return token中包含的用户名、id
     */
    public static Map getTokenUserInfo(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
//            String payload = jwt.getClaim("payload").asString();
            String userName = jwt.getClaim("userName").asString();
            Map<String  , Object> payload = new HashMap<>();
            payload.put("userName" , userName);
            return payload;
        } catch (JWTDecodeException e) {
            return null;
        }
    }
    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的用户名
     */
    public static String getUsername(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("userName").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }


    /**
     * 生成签名,5min后过期
     * @param payload 载荷，用来存放有效信息
     * @param secret 用户的密码
     * @return 加密的token
     */
    public static String sign(Map<String, Object> payload, String secret) {
        try {
            Date date = new Date(System.currentTimeMillis()+EXPIRE_TIME);
            Algorithm algorithm = Algorithm.HMAC256(secret);

            // 附带username信息
            return JWT.create()
                    .withClaim("payload", JSON.toJSONString(payload))
                    .withClaim("userName", payload.get("userName").toString())
                    .withExpiresAt(date)
                    .sign(algorithm);

        } catch (UnsupportedEncodingException e) {
            return null;
        }
    }



    /**
     * 获取用户名
     * @param token
     * @return
     */
    public static String getUserName(String token) {
        Map info = getTokenUserInfo(token);
        assert info != null;
        return (String)info.get("userName");
    }

    /**
     * 获取用户角色
     * @param token
     * @return
     */
    public static List getUserRole(String token) {
        Map info = getTokenUserInfo(token);
        return (List)info.get("role");
    }

    /**
     * 获取用户id
     * @param token
     * @return
     */
    public static Long getUserId(String token) {
        Map info = getTokenUserInfo(token);
        return  Long.valueOf(info.get("id").toString());
    }

    public static void main(String[] args) {

        HashMap<String, Object> map = new HashMap<>();
        map.put("id", "1");
        map.put("userName", "owen");
        String token = sign(map, "123456");
        System.out.println(token);

//        token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6Im93ZW4iLCJleHAiOjE1ODMyMjkxMDZ9.z2Ggxd6p8sYwGhdYV8u0BNXtwC5PyZlusjwbT2l1tfk";
        boolean owen = verify(token, "owen", "123456");
        System.out.println(owen);

        System.out.println(getUserId(token));


    }
}
