package com.skr.mdm.netty;

import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.SM2;
import cn.hutool.crypto.digest.DigestUtil;
import com.skr.mdm.dto.WebsocketDTO;
import com.skr.mdm.enums.MdmEncryptEnum;
import com.skr.mdm.util.SmUtils;
import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

/**
 * @author nfq
 * @date 2020/7/28 18:36
 */
@Slf4j
public class WebsocketDecoder {

    public static WebsocketDTO decoder(ByteBuf byteBuf, String mdmEncrypt) {
        if (MdmEncryptEnum.SM.getMdmEncrypt().equals(mdmEncrypt)) {
            return decoderBySm(byteBuf);
        } else {
            return decoderByMd5(byteBuf);
        }
    }

    public static WebsocketDTO decoderByMd5(ByteBuf byteBuf) {
        byteBuf.markReaderIndex();
        // 类型
        short cmdType = byteBuf.readShort();
        // 长度
        int length = byteBuf.readInt();
        // 签名
        byte[] signByte = new byte[32];
        byteBuf.readBytes(signByte);
        String sign = new String(signByte);
        // 消息体
        byte[] lengthByte = new byte[length];
        byteBuf.readBytes(lengthByte);
        String body = new String(lengthByte);

        if (!StringUtils.equalsIgnoreCase(sign, DigestUtil.md5Hex(body))) {
            log.error("签名校验失败");
            return null;
        }
        return WebsocketDTO.builder().type(cmdType).length(length).sign(sign).body(body).build();
    }


    public static WebsocketDTO decoderBySm(ByteBuf byteBuf) {
        byteBuf.markReaderIndex();
        // 类型
        short cmdType = byteBuf.readShort();
        // 长度
        int length = byteBuf.readInt();
        // 签名
        byte[] signByte = new byte[64];
        byteBuf.readBytes(signByte);
        String sign = new String(signByte);
        // 消息体
        byte[] lengthByte = new byte[length];
        byteBuf.readBytes(lengthByte);
        String body = new String(lengthByte);

        SM2 sm2 = SmUtils.sm2Crypt();
        String sm3 = SmUtil.sm3(body);
        if (!sm2.verifyHex(sm3, HexUtil.encodeHexStr(signByte))) {
            log.error("签名校验失败");
            return null;
        }
        return WebsocketDTO.builder().type(cmdType).length(length).sign(sign).body(body).build();
    }

}
