package com.pj.project.sys_user_sync.listen;

import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;

import com.pj.current.config.SystemObject;
import com.pj.project.sys_user_sync.Sm4Util;
import com.pj.project4sp.config.SpConfigUtil;
import com.pj.utils.sg.AjaxError;
import com.pj.utils.sg.IpUtil;
import com.pj.utils.so.SoMap;

import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.sso.SaSsoManager;
import cn.dev33.satoken.strategy.SaStrategy;

/**
 * 接收推送 - 数据读取工具类
 *
 * @author click33
 * @since 2022/11/22
 */
public class SspServerListenUtil {

    /**
     * 获取一个请求中的 Data 数据
     * @param request 请求对象
     */
    public static SoMap getData(HttpServletRequest request) {

    	// ---- 第0步，校验IP 
    	List<String> ipList = SpConfigUtil.listenIpList();
    	String ip = IpUtil.getIP(request);
    	if(SaStrategy.me.hasElement.apply(ipList, ip) == false) {
    		throw new AjaxError("非法IP：" + ip);
    	}
    	
        // ---- 第1步，获取参数
        String data = request.getParameter("data");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String sign = request.getParameter("sign");

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

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

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

        // 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, SaSsoManager.getConfig().getSecretkey(), sign);

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

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

        // 3.3 返回 dataMap
        return SoMap.getSoMap(dataMap);
    }

}