package com.muchinfo.mtp3common.utils;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.apache.shiro.util.SimpleByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import org.apache.shiro.codec.Hex;

import java.util.Base64;
import java.util.Random;

public class EncryptionUtils {

    private static final String AES_ALGORITHM = "AES";
    private static final int KEY_SIZE = 128;
    @SuppressWarnings("unused")
    private static final int CACHE_SIZE = 1024;
    private static final String AES_SECRET_KEY = "0d299ce2d4105282f7471074cb0f9f9d";
    @SuppressWarnings("unused")
    private static final String AES_SEED = "";
    @SuppressWarnings("unused")
    private static Cipher aesCipher = null;
    @SuppressWarnings("unused")
    private static final String CODE_TYPE_BASE64 = "BASE64";
    @SuppressWarnings("unused")
    private static final String CODE_TYPE_HEX = "HEX";

    @SuppressWarnings("unused")
    private static final String SHA_KEY = "SHA";

    private static final String SHA_KEY_256 = "SHA-256";

    /**
     * <p>
     * 生成密钥
     * </p>
     *
     * @param seed 密钥种子
     * @return
     * @throws Exception
     */
    public static String getSecretKey(String seed) throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(AES_ALGORITHM);
        SecureRandom secureRandom;
        if (seed != null && !"".equals(seed)) {
            secureRandom = new SecureRandom(seed.getBytes());
        } else {
            secureRandom = new SecureRandom();
        }
        keyGenerator.init(KEY_SIZE, secureRandom);
        SecretKey secretKey = keyGenerator.generateKey();
        String key = Hex.encodeToString(secretKey.getEncoded());
        System.out.println(key);
        return key;
    }

    /**
     * <p>
     * 加密
     * </p>
     *
     * @return jdbc_username=mtp2_manage
    jdbc_password=mtpmuchinfo
     * @throws Exception
     * AES-128-ECB  那串KEY，不要直接当成字符串密钥，要先hexdecode成二进制，再用来当密钥
     */
    public static String encryptByAES(String text) {
        String cryptographic = "";
        if(StringUtils.isBlank(text)) return null;

        synchronized(EncryptionUtils.class) {
            try {
                byte[] raw = Hex.decode(AES_SECRET_KEY);
                SecretKeySpec secretKeySpec = new SecretKeySpec(raw, AES_ALGORITHM);
                Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
                cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
                byte[] aesData = cipher.doFinal(text.getBytes("utf-8"));
                cryptographic = Hex.encodeToString(aesData);
                //                System.out.println(cryptographic);
            } catch (Exception e) {
                // : handle exception
                e.printStackTrace();
            }
        }

        return cryptographic;
    }


    /**
     * <p>
     * 解密
     * </p>
     *
     * @return
     * @throws Exception
     */
    public static String decryptForAES(String cryptographic) {
        String txt = "";
        if(StringUtils.isBlank(cryptographic)){
            return txt;
        }
        try {
                byte[] raw = Hex.decode(AES_SECRET_KEY);
            SecretKeySpec secretKeySpec = new SecretKeySpec(raw, AES_ALGORITHM);
            Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            byte[] txtData = cipher.doFinal(Hex.decode(cryptographic));
            txt = new String(txtData, "utf-8");
            //            System.out.println(txt);
        } catch (Exception e) {
            e.printStackTrace();
            txt = cryptographic;
        }

        return txt;
    }

    public static String decryptForAES(String cryptographic,String sign) {
        String txt = "";
        if(StringUtils.isBlank(cryptographic)){
            return txt;
        }
        try {
            byte[] decoded = Hex.decode(cryptographic);
            SecretKeySpec secretKeySpec = new SecretKeySpec(sign.getBytes(StandardCharsets.UTF_8), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            byte[] decrypted = cipher.doFinal(decoded);
            return new String(decrypted, StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
            txt = cryptographic;
        }

        return txt;
    }

    /**
     * SHA256加密
     * @Title: encryptSHA
     * @Description:
     * @param str
     * @return
     * String
     * @throws
     */
    public static String encryptSHA(String str){
        try {
            byte[] str_ = str.getBytes("UTF-8");
            MessageDigest md = MessageDigest.getInstance(SHA_KEY_256);
            md.update(str_);

            byte[] pd_ = md.digest();
            return Hex.encodeToString(pd_);
        } catch (Exception e) {
            // : handle exception
            e.printStackTrace();
            return null;
        }
    }
}
