package com.ruoyi.dj.mqtt.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class JsonKeyRemover {
    /**
     * 从 JSON 字符串中移除指定的键（包括嵌套路径键）
     */
    public static String removeKeysFromJson(List<String> keysToRemove, String jsonString) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode rootNode = mapper.readTree(jsonString);

        // 递归移除指定的键
        removeKeysRecursive(rootNode, keysToRemove);

        return mapper.writeValueAsString(rootNode);
    }

    /**
     * 递归地从 JsonNode 中移除指定的键
     */
    private static void removeKeysRecursive(JsonNode node, List<String> keysToRemove) {
        if (node.isObject()) {
            ObjectNode objectNode = (ObjectNode) node;

            // 在当前级别移除键
            for (String key : keysToRemove) {
                if (objectNode.has(key)) {
                    objectNode.remove(key);
                }
            }

            // 遍历剩余的字段
            Iterator<Map.Entry<String, JsonNode>> fields = objectNode.fields();
            while (fields.hasNext()) {
                Map.Entry<String, JsonNode> entry = fields.next();
                // 递归处理子节点
                removeKeysRecursive(entry.getValue(), keysToRemove);
            }
        } else if (node.isArray()) {
            // 如果节点是数组，处理每个元素
            for (JsonNode arrayElement : node) {
                removeKeysRecursive(arrayElement, keysToRemove);
            }
        }
    }

    /**
     * 为 JSON 字符串的最外层添加一个新的字段
     */
    public static String addKeyToRoot(String jsonString, String keyToAdd, Object valueToAdd) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode rootNode = mapper.readTree(jsonString);

        // 将传入的 Object 转换为 JsonNode
        JsonNode valueNode = mapper.valueToTree(valueToAdd);

        if (rootNode.isObject()) {
            ((ObjectNode) rootNode).set(keyToAdd, valueNode);
        }

        return mapper.writeValueAsString(rootNode);
    }
}
