package cn.muchinfo.rma.netcore.crypto;

import android.annotation.SuppressLint;

import com.blankj.utilcode.util.LogUtils;

import java.nio.charset.StandardCharsets;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

/**
 * 5.0报文加解密
 */
public class Packet50Crypto {
    private static final String AES_SECRET_KEY = "F7A72DE7D6264530F01BA49BC73EB873";
    private static final String MAC_KEY_DES = "B0FB83E39A5EBFAABE471362A58393FF";
    private static final String MAC_KEY = "D951DBE037C82325";

    private static final String KEY_ALGORITHM = "AES";
    private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS7Padding";

    /**
     * 5.0报文内容加密
     * @param planText 明文
     * @return 密文
     */
    public static byte[] encrypt(byte[] planText) {
        byte[] ret;

        try {
            // AES加密
            @SuppressLint("GetInstance") Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC");
            SecretKeySpec keySpec = new SecretKeySpec(AES_SECRET_KEY.getBytes(StandardCharsets.UTF_8), KEY_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);

            byte[] encryptData = cipher.doFinal(planText);

            ret = new byte[4 + encryptData.length + 8];

            // 这里需要的是明文长度
            byte[] _len = intToByte(planText.length);
            // 长度 4 byte
            System.arraycopy(_len, 0, ret, 0, _len.length);
            // 内容
            System.arraycopy(encryptData, 0, ret, _len.length, encryptData.length);
            // MAC校验码 8 byte
            byte[] macSrcBytes = new byte[8];
            System.arraycopy(_len, 0, macSrcBytes, 0, _len.length);
            BaseDES baseDES = new BaseDES();
            byte[] macProof = baseDES.proofMacData(macSrcBytes, stringToHex(MAC_KEY_DES), stringToHex(MAC_KEY));
            System.arraycopy(macProof, 0, ret, encryptData.length + 4, macProof.length);
        } catch (Exception e) {
            ret = new byte[0];
        }

        return ret;
    }

    /**
     * 5.0报文内容解密
     * @param contentData 报文内容
     * @return 明文
     */
    public static byte[] decrypt(byte[] contentData) {
        byte[] rst = null;

        try {
            // 获取内容里的密文
            byte[] encryptData = new byte[contentData.length - 4 - 8]; // 暂不进行MAC校验
            System.arraycopy(contentData, 4, encryptData, 0, encryptData.length);

            // AES解密
            @SuppressLint("GetInstance") Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC");
            SecretKeySpec key = new SecretKeySpec(AES_SECRET_KEY.getBytes(StandardCharsets.UTF_8), KEY_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, key);
            rst = cipher.doFinal(encryptData);
        } catch (Exception e) {
            LogUtils.eTag("RMA", e.toString());
        }

        return rst;
    }

    private static byte[] intToByte(int i) {
        byte[] byt = new byte[4];
        for (int j = 0; j < 4; j++) {
            byt[j] = (byte) (i >> 8 * j & 0xFF);
        }
        return byt;
    }

    private static int getInt(char c) {
        if (c >= '0' && c <= '9') {// 转化为10进制
            return c - '0';
        } else if (c >= 'A' && c <= 'Z') {
            return c - 'A' + 10;
        } else if (c >= 'a' && c <= 'z') {
            return c - 'a' + 10;
        }
        return 999;
    }

    private static byte[] stringToHex(String string) {
        if (string.length() % 2 != 0) {// 不行
            return null;
        }
        byte[] bs = new byte[string.length() / 2];
        char[] cs = string.toCharArray();
        int height = 0;
        int low = 0;
        for (int i = 0; i < cs.length; i += 2) {//
            height = getInt(cs[i]);
            low = getInt(cs[i + 1]);

            if (low == 999 || height == 999) {
                return null;
            }

            int byteValue = height * 16 + low;
            bs[i / 2] = (byte) byteValue;
        }
        System.gc();
        return bs;
    }
}
