package com.pj.usersync;

import cn.dev33.satoken.SaManager;
import com.pj.utils.JsonUtil;
import com.pj.utils.Sm4Util;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.TreeMap;

/**
 * 接收广播 - 数据读取工具类
 *
 * @author click33
 * @since 2022/11/22
 */
public class SspClientListenUtil {

    /** 接口签名秘钥 */
    public static final String signKey = "YQfyZtAmDbYHTBaHPSx3GZeX7x2ip7ik";

    /** SM4数据加密秘钥 */
    public static final String sm4Key = "uYdc58GHjd4TjsHe";

    /** 接口调用时的时间戳允许的差距（单位：ms），-1代表不校验差距  (1000  * 60 * 10 = 10分钟) */
    public static final long allowTimestampDisparity = 1000  * 60 * 10;

    /** 接受的数据是否使用SM4解密 */
    public static final boolean isSm4Decrypt = true;

    /**
     * 获取一个请求中的 Data 数据
     * @param request 请求对象
     */
    public static Map<String, Object> getData(HttpServletRequest request) {

        // ---- 第1步，获取参数
        String data = request.getParameter("data");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String sign = request.getParameter("sign");

        // ---- 第2步，校验参数

        // 2.1 参数不能为空
        notIsNull(data, "必须提供 data 参数");
        notIsNull(timestamp, "必须提供 timestamp 参数");
        notIsNull(nonce, "必须提供 nonce 参数");
        notIsNull(sign, "必须提供 sign 参数");

        // 2.2 校验时间戳 timestamp 与当前时间的差距是否超出限制
        SaManager.getSaSignTemplate().checkTimestamp(Long.parseLong(timestamp), allowTimestampDisparity);

        // 2.3 校验 sign 签名是否正确
        Map<String, Object> paramsMap = new TreeMap<>();
        paramsMap.put("data", data);
        paramsMap.put("timestamp", timestamp);
        paramsMap.put("nonce", nonce);
        SaManager.getSaSignTemplate().checkSign(paramsMap, signKey, sign);

        // ---- 第3步，解码 data 参数
        // 3.1 解析出 json 字符串
        String dataJson = data;
        if(isSm4Decrypt) {
            dataJson = Sm4Util.decrypt(data, sm4Key);
        }

        // 3.2 json 字符串转 Map 对象
        Map<String, Object> dataMap = JsonUtil.parseJsonToMap(dataJson);

        // 3.3 返回 dataMap
        return dataMap;
    }

    /**
     * 如果给定的数据为null，则抛出异常
     */
    public static void notIsNull(Object value, String errorMsg) {
        if(value == null || value.equals("")) {
            throw new RuntimeException(errorMsg);
        }
    }

}