package thyyxxk.webserver.utils;

import cn.hutool.crypto.asymmetric.SM2;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.util.encoders.Hex;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

public class EncryptUtil {

    public static void main(String[] args) {
        sign(new JSONObject());
    }

    public static void sign(JSONObject jsonObject) {

        jsonObject = JSONObject.parseObject("{\"appId\":\"43AF047BBA47FC8A1AE8EFB2XXXXXXXX\", " +
                "\"data\":{\"appId\":\"43AF047BBA47FC8A1AE8EFB2XXXXXXXX\",\"userName\":\"测试\",\"appUserId\":\"o8z4C5avQXqC0aWFPf1Mzu6D7WC\n" +
                "Q_bd\",\"idNo\":\"350181199011193519\",\"idType\":\"01\",\"phoneNumber\":\"13763873033\"}, \"encType\":\"SM4\", \"signData\":\"URVQNdVNn5mz2EhKZhLTlXNwAWTSncFoSe8Ilx7jhn81eABJ46sdRRN1ZiAiQjPUTixG9bwqEhiJupH\n" +
                "RGmyO5w==\", \"signType\":\"SM2\", \"timestamp\":\"20200207175759\", \"version\":\"2.0.1\"\n" +
                "}");

        // 生成原始签名串
        SortedMap<String, Object> treeMap = new TreeMap<>(jsonObject);
        String rawStr = getParamsFromMap(treeMap) + "key=4117E877F5FA0A0188891283E4B617D5";

        System.out.println(SM2Sign(rawStr));
    }

    private static String SM2Sign(String raw) {
        byte[] message = Hex.decode(raw);
        return raw;
    }

    private static String getParamsFromMap(SortedMap<String, Object> map) {
        // sign不参与签名
        map.remove("signData");
        map.remove("encData");
        map.remove("extra");
        StringBuilder sb = new StringBuilder();
        Set<Map.Entry<String, Object>> es = map.entrySet();
        Iterator<Map.Entry<String, Object>> it = es.iterator();
        while (it.hasNext()) {
            Map.Entry<String, Object> entry = it.next();
            String k = entry.getKey();
            Object objVal = entry.getValue();
            if (objVal == null) { //值为空的参数不参与签名
                continue;
            }
            String v;
            if (isBaseDataType(objVal.getClass())) {
                v = objVal.toString();
            } else {
                v = JSON.toJSONString(objVal, SerializerFeature.MapSortField);
            }
            if (!v.equals("")) {
                if (it.hasNext()) {
                    sb.append(k).append("=").append(v).append("&");
                } else {
                    sb.append(k).append("=").append(v);
                }
            }
        }
        return sb.toString();
    }

    private static boolean isBaseDataType(Class clazz) {
        return (clazz.equals(String.class) || clazz.equals(Integer.class) || clazz.equals(Byte.class)
                || clazz.equals(Long.class) || clazz.equals(Double.class) || clazz.equals(Float.class)
                || clazz.equals(Character.class) || clazz.equals(Short.class) || clazz.equals(BigDecimal.class)
                || clazz.equals(BigInteger.class) || clazz.equals(Boolean.class) || clazz.equals(Date.class) || clazz.isPrimitive());
    }
}
