package com.eactive.eai.custom.transformer.function.userdefined;

import com.eactive.eai.common.context.ElinkTransactionContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.spi.json.JacksonJsonNodeJsonProvider;
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
import org.nfunk.jep.ParseException;
import org.nfunk.jep.function.PostfixMathCommand;

import java.util.Stack;

public class JsonPathExtractRequestMessage extends PostfixMathCommand {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    public JsonPathExtractRequestMessage() {
        numberOfParameters = -1;
    }

    public void run(Stack inStack) throws ParseException {
        checkStack(inStack);

        String bizData = ElinkTransactionContext.getRequestBizData();

        Object p1 = inStack.pop();
        String path = String.valueOf(p1);

        inStack.clear();

        try {
            // Jackson을 JsonPath의 JSON 프로바이더로 설정
            Configuration config = Configuration.builder()
                    .jsonProvider(new JacksonJsonNodeJsonProvider())
                    .build();

            JsonNode resultNode = JsonPath.using(config).parse(bizData).read(path);

            if (resultNode == null) {
                inStack.push(null);
            } else if (resultNode.isValueNode()) {
                // 단순 값(문자열, 숫자, boolean 등)은 텍스트로 반환
                inStack.push(resultNode.asText());
            } else {
                // 객체/배열은 JsonNode 그대로 반환
                inStack.push(resultNode);
            }
        } catch (Exception e) {
            throw new ParseException("JsonPath extract error: " + e.getMessage());
        }
    }

    private JsonNode getNodeAtPath(JsonNode rootNode, String path) {
        String[] tokens = path.split("/");
        JsonNode currentNode = rootNode;

        for (String token : tokens) {
            if (token.isEmpty()) continue;

            if (token.matches("\\d+")) {
                currentNode = currentNode.get(Integer.parseInt(token));
            } else {
                currentNode = currentNode.get(token);
            }

            if (currentNode == null) {
                return null;
            }
        }
        return currentNode;
    }
}
