package com.inkasso.adapter.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.inkasso.adapter.bean.AbstractUser;
import com.inkasso.adapter.constance.JwtTokenConstant;
import com.inkasso.adapter.enums.ClientTypeEnum;
import com.inkasso.adapter.exception.ServiceException;
import com.inkasso.adapter.exception.enums.ExceptionEnum;
import lombok.Getter;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>jwt token工具类</p>
 * <pre>
 *     jwt的claim里一般包含以下几种数据:
 *         1. iss -- token的发行者
 *         2. sub -- 该JWT所面向的用户
 *         3. aud -- 接收该JWT的一方
 *         4. exp -- token的失效时间
 *         5. nbf -- 在此时间段之前,不会被处理
 *         6. iat -- jwt发布时间
 *         7. jti -- jwt唯一标识,防止重复使用
 * </pre>
 * Claims 放了4部分信息
 * <p>
 * userType 用户类型 clientType  客户端类型 userId   用户id tenantId 租户id account  登陆账户
 *
 * @author zc
 * @Date 2021-08-06
 */
@Component
@Getter
public class JwtHS256Util {

  protected Log log = LogFactory.getLog(this.getClass());
  /**
   * 创建秘钥
   */
  private static final String SECRET =  "www.kafubao.com";

  /**
   * 过期时间5秒
   */
  private static final long EXPIRE_TIME = 1000L*60*60*24*365*10;


  /**
   * 生成Token
   * @return
   */
  public static String buildJWT(ClientTypeEnum clientTypeEnum, AbstractUser abstractUser) {
    // 生成的时间
    Date createTime = new Date();
    // 创建过期时间1天
    Calendar nowTime = Calendar.getInstance();
    // 当前时间加上 10年
    nowTime.add(Calendar.YEAR, 10);
    // 得到过期时间
    Date expireTime = nowTime.getTime();
    // 设置header信息
    HashMap<String, Object> header = new HashMap<>(4);
//    header.put("alg", "HS256");
//    header.put("typ", "JWT");
    // 生成token
    String token = JWT.create()
            .withHeader(header) // 设置头部
            .withClaim(JwtTokenConstant.USER_ID, abstractUser.getId()) // 设置载荷
            .withClaim(JwtTokenConstant.CLIENT_TYPE,clientTypeEnum.getCode())//
            .withClaim(JwtTokenConstant.LOGIN_TIME,new Date())
//            .withIssuedAt(createTime) // 创建时间
//            .withExpiresAt(expireTime)  // 过期时间
            .sign(Algorithm.HMAC256(SECRET)); // 设置签名秘钥
    return token;

  }


  public static Map<String, Claim> getClaims(String token){
    Map<String, Claim> claims = null;
    try {
      claims = JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token).getClaims();
    }catch (Exception e){
      e.printStackTrace();
      throw new ServiceException(401, ExceptionEnum.ACCESS_ERROR);
    }

    return claims;



  }


}