package com.remax.visualnovel.api.interceptor.util;

import java.nio.charset.StandardCharsets;

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

import timber.log.Timber;

public class AES {

    private static final String KEY_SUFFIX = "90e8kDQUIWpXg8Jp";

    /**
     * For a 128-bit AES key you need 16 bytes.
     * For a 256-bit AES key you need 32 bytes.
     */
    public static String KEY;

    /**
     * IV length: must be 16 bytes long
     */
    public static final String IV = "sdf4ddfsFD86Vdf2";

    private AES() {
    }

    public static void genKey(String token) {
        //token加密最多截取前32位
        String encodeStr = (token.length() > 32 ? token.substring(0, 32) : token) + KEY_SUFFIX;
        KEY = Md5.encode(encodeStr).toUpperCase();
        Timber.d("genKey: %s", KEY);
    }

    public static String encrypt(String data) {
        return encrypt(data, KEY, IV);
    }

    public static String desEncrypt(String data) {
        return desEncrypt(data, KEY, IV);
    }

    public static String encrypt(String data, String key, String initVector) {
        try {
            IvParameterSpec iv = new IvParameterSpec(initVector.getBytes(StandardCharsets.UTF_8));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

            byte[] encrypted = cipher.doFinal(data.getBytes());
            return Base64.encode(encrypted);
        } catch (Exception ex) {
            ex.printStackTrace();
            return data;
        }
    }

    public static String desEncrypt(String data, String key, String initVector) {
        try {
            byte[] encrypted = Base64.decode(data);
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(initVector.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);

            byte[] original = cipher.doFinal(encrypted);

            return new String(original);
        } catch (Exception e) {
            e.printStackTrace();
            return data;
        }
    }
}
