package com.agent.management.engine;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.*;

/**
 * JSON 嵌套路径取值工具。
 *
 * <p>支持点号分隔路径，数组使用数字下标：
 * <ul>
 *   <li>{@code output.total.result} → value["output"]["total"]["result"]</li>
 *   <li>{@code items.0.name} → value["items"][0]["name"]</li>
 * </ul>
 */
public class JsonPathExtractor {

    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 从对象中按点号路径取值。
     *
     * @param root 根对象（Map / JsonNode / POJO / Collection）
     * @param path 点号路径，可为 null 或空（表示取 root 本身）
     * @return 路径对应的值；路径不存在返回 null
     */
    public static Object extract(Object root, String path) {
        if (root == null) {
            return null;
        }
        if (path == null || path.isBlank()) {
            return root;
        }
        Object current = root;
        String[] segments = path.split("\\.");
        for (String segment : segments) {
            if (segment.isEmpty()) {
                continue;
            }
            current = step(current, segment);
            if (current == null) {
                return null;
            }
        }
        return current;
    }

    private static Object step(Object current, String segment) {
        if (current instanceof Map<?, ?> map) {
            return map.get(segment);
        }
        if (current instanceof JsonNode node) {
            if (node.isArray()) {
                Integer idx = parseIndex(segment);
                return idx != null && idx >= 0 && idx < node.size() ? jsonNodeToValue(node.get(idx)) : null;
            }
            JsonNode child = node.get(segment);
            return child == null ? null : jsonNodeToValue(child);
        }
        if (current instanceof Collection<?> collection) {
            Integer idx = parseIndex(segment);
            if (idx == null || idx < 0) {
                return null;
            }
            int i = 0;
            for (Object item : collection) {
                if (i == idx) {
                    return item;
                }
                i++;
            }
            return null;
        }
        // POJO：先转 Map 再取字段
        try {
            JsonNode node = MAPPER.valueToTree(current);
            JsonNode child = node.get(segment);
            return child == null ? null : jsonNodeToValue(child);
        } catch (Exception e) {
            return null;
        }
    }

    private static Integer parseIndex(String segment) {
        try {
            return Integer.parseInt(segment);
        } catch (NumberFormatException e) {
            return null;
        }
    }

    private static Object jsonNodeToValue(JsonNode node) {
        if (node == null || node.isNull()) {
            return null;
        }
        if (node.isTextual()) {
            return node.asText();
        }
        if (node.isNumber()) {
            return node.numberValue();
        }
        if (node.isBoolean()) {
            return node.booleanValue();
        }
        try {
            return MAPPER.treeToValue(node, Object.class);
        } catch (Exception e) {
            return node.toString();
        }
    }
}
