package com.ruoyi.platform.utils;

import com.alibaba.fastjson.JSON;

import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AIM64EncoderUtil {

    private static final String AIM64_ENCODING_PREFIX = "O-";

    private static final Map<String, String> BS64_REPLACE_CHARACTERS_ENCODING = new HashMap<>();
    static {
        BS64_REPLACE_CHARACTERS_ENCODING.put("=", "");
        BS64_REPLACE_CHARACTERS_ENCODING.put("+", "-");
        BS64_REPLACE_CHARACTERS_ENCODING.put("/", "_");
    }

    public static String aim64encode(Map<String, Object> value) {
        // 将Map对象转换为JSON字符串
        String jsonEncoded = JSON.toJSONString(value);
        // 将JSON字符串进行Base64编码
        String base64Encoded = Base64.getEncoder().encodeToString(jsonEncoded.getBytes());
        String aim64Encoded = base64Encoded;
        // 替换Base64编码中的特定字符
        for (Map.Entry<String, String> entry : BS64_REPLACE_CHARACTERS_ENCODING.entrySet()) {
            aim64Encoded = aim64Encoded.replace(entry.getKey(), entry.getValue());
        }
        // 返回带有前缀的AIM64编码字符串
        return AIM64_ENCODING_PREFIX + aim64Encoded;
    }


    // 这是一个静态方法，用于将 Map 对象 value 编码为字符串
    public static String encode(Map<String, Object> value, boolean oneWayHashing) {
        // 如果 oneWayHashing 参数为 true，表示使用一种不可逆的哈希算法
        if (oneWayHashing) {
            // 使用 MD5 算法将 value 对象转换为字符串
            return md5(JSON.toJSONString(value));
        }
        // 如果 oneWayHashing 参数为 false，表示使用一种可逆的编码算法
        return aim64encode(value);
    }


    //  MD5 加密函数，用于将输入字符串转换为 MD5 加密后的字符串。
    private static String md5(String input) {
        // 尝试获取 MD5 加密对象
        try {
            java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
            // 使用 MD5 对象对输入字符串进行加密
            byte[] array = md.digest(input.getBytes());
            // 创建一个 StringBuilder 对象，用于将加密后的字节转换为字符串
            StringBuilder sb = new StringBuilder();
            // 遍历加密后的字节数组
            for (byte b : array) {
                // 将每个字节转换为 16 进制字符串
                sb.append(Integer.toHexString((b & 0xFF) | 0x100).substring(1, 3));
            }
            // 返回加密后的字符串
            return sb.toString();
        } catch (java.security.NoSuchAlgorithmException e) {
            // 如果在获取 MD5 加密对象时出现了错误，则打印错误信息
            e.printStackTrace();
        }
        // 如果出现了错误，则返回 null
        return null;
    }

    // 这是一个 decode 方法，用于将 runIds 列表转换为查询字符串
    public static String decode(List<String> runIds) {
        // 确保 runIds 列表的大小为 3
        if (runIds == null || runIds.size() == 0) {
            // 如果 runIds 为空，抛出 IllegalArgumentException 异常
            throw new IllegalArgumentException("runIds 不能为空");
        }
        // 构建查询字符串
        StringBuilder queryBuilder = new StringBuilder("run.hash in [");
        // 遍历 runIds 列表
        for (int i = 0; i < runIds.size(); i++) {
            // 如果当前不是第一个元素，添加逗号
            if (i > 0) {
                queryBuilder.append(",");
            }
            // 将当前元素添加到查询字符串中，使用双引号括起来
            queryBuilder.append("\"").append(runIds.get(i)).append("\"");
        }
        // 将查询字符串闭合
        queryBuilder.append("]");
        // 将查询字符串转换为字符串
        String query = queryBuilder.toString();
        // 创建一个 Map 对象，用于存储查询参数
        Map<String, Object> map = new HashMap<>();
        // 将查询字符串添加到 Map 中
        map.put("query", query);
        // 将 advancedMode 设置为 true
        map.put("advancedMode", true);
        // 将 advancedQuery 设置为查询字符串
        map.put("advancedQuery", query);

        // 使用 encode 方法将 Map 对象转换为查询字符串
        String searchQuery = encode(map, false);
        // 返回查询字符串
        return searchQuery;

    }
}
