package com.om.utils;



import com.om.entity.dto.GuidDTO;
import com.om.entity.dto.ObsDTO;
import com.om.exception.BizException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class AesUtil {
    private static final String key = "hG75bY3u9zXkQpD2";


    /**
     * 加密
     * @param sSrc 需要加密的字符串
     * @return
     * @throws Exception
     */
    public static String Encrypt(String sSrc) throws Exception {

        // 判断Key是否为16位
        if (key.length() != 16) {
            System.out.print("Key长度不是16位");
            return null;
        }
        byte[] raw = key.getBytes("utf-8");
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//"算法/模式/补码方式"
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8"));

        return new Base64().encodeToString(encrypted);//此处使用BASE64做转码功能，同时能起到2次加密的作用。
    }

    /**
     * 解密
     * @param sSrc 需要解密的字符串
     * @return
     * @throws Exception
     */
    public static String Decrypt(String sSrc) throws Exception {
        try {
            // 判断Key是否正确
            if (key == null) {
                System.out.print("Key为空null");
                return null;
            }
            // 判断Key是否为16位
            if (key.length() != 16) {
                System.out.print("Key长度不是16位");
                return null;
            }
            byte[] raw = key.getBytes("utf-8");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);
            byte[] encrypted1 = new Base64().decode(sSrc);//先用base64解密
            try {
                byte[] original = cipher.doFinal(encrypted1);
                String originalString = new String(original,"utf-8");
                return originalString;
            } catch (Exception e) {
                System.out.println(e.toString());
                return null;
            }
        } catch (Exception ex) {
            System.out.println(ex.toString());
            return null;
        }
    }


    public static String generateGuid(Map<String, Object> claims){
        try {
            String encrypt = Encrypt(claims.toString());
            return encrypt;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static GuidDTO getGuidDTOFromGuid(String guid){
        GuidDTO dto = new GuidDTO();
        try {
            String decrypt = Decrypt(guid);
            GuidDTO guidDTO = parseGuidDTO(decrypt);
            return guidDTO;
        } catch (Exception e) {
            throw new BizException("guid转换失败");
        }
    }
    public static GuidDTO parseGuidDTO(String guid) {
        guid = guid.substring(1, guid.length() - 1); // 去除字符串两端的大括号
        String[] keyValuePairs = guid.split(", ");

        Map<String, String> keyValueMap = new HashMap<>();
        for (String pair : keyValuePairs) {
            String[] keyValue = pair.split("=");
            if(keyValue.length!=2){
                continue;
            }
            keyValueMap.put(keyValue[0], keyValue[1]);
        }

        String appVersion = keyValueMap.get("appVersion");
        int u_id = Integer.parseInt(keyValueMap.get("u_id"));
        String clientNum = keyValueMap.get("clientNum");
        String deviceSn = keyValueMap.get("deviceSn");

        return new GuidDTO(u_id,deviceSn,appVersion,clientNum);
    }

    public static String generateObs(Map<String, Object> claims){
        try {
            String encrypt = Encrypt(claims.toString());
            return encrypt;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static ObsDTO getObsDTO(String obs){
        ObsDTO dto = new ObsDTO();
        try {
            String decrypt = Decrypt(obs);
            ObsDTO guidDTO = parseObsDTO(decrypt);
            return guidDTO;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static ObsDTO parseObsDTO(String obs) {
        obs = obs.substring(1, obs.length() - 1); // 去除字符串两端的大括号
        String[] keyValuePairs = obs.split(", ");

        Map<String, String> keyValueMap = new HashMap<>();
        for (String pair : keyValuePairs) {
            String[] keyValue = pair.split("=");
            if(keyValue.length!=2){
                continue;
            }
            keyValueMap.put(keyValue[0], keyValue[1]);
        }

        String ak = keyValueMap.get("ak");
        String sk = keyValueMap.get("sk");
        String endpoint = keyValueMap.get("endpoint");

        return new ObsDTO(ak,sk,endpoint);
    }


    public static void main(String[] args) throws Exception {
        /*
         * 此处使用AES-128-ECB加密模式，key需要为16位。
         */
        // 加密
/*       Map<String,Object> claims = new HashMap<>();
        claims.put("u_id", 1);
        claims.put("deviceSn", "123456");
        claims.put("appVersion", "v3.0");
        claims.put("clientNum", "1234");
        String guid = generateGuid(claims);
        System.out.println("加密后的字串是：" + guid);

        // 解密
        GuidDTO guidDTOFromGuid = getGuidDTOFromGuid(guid);
        System.out.println("解密后的字串是：" + guidDTOFromGuid);*/

        //加密密码
        String password = Encrypt("123456");
        System.out.println("加密的密码是："+password);

        //密码解密
        String decrypt = Decrypt("v6MnUQze567c7vJWwS/yt4XlmgEE9yE/SGZfZpWujSg=");
        System.out.println(decrypt);
    }


}

