package com.easyagents.flow.core.test;

import com.easyagents.flow.core.util.TextTemplate;
import org.junit.Assert;
import org.junit.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * 验证文本模板能解析带点号的扁平 key，例如 `nodeId.paramName`。
 */
public class TextTemplatePathTest {

    @Test
    public void shouldResolveFlatScopedKeyBeforeJsonPathFallback() {
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("node_1.user_input", "你好啊");

        String result = TextTemplate.of("{{node_1.user_input}}").formatToString(parameters);

        Assert.assertEquals("你好啊", result);
    }

    @Test
    public void shouldResolveFlatScopedNumericKeyFromMergedContext() {
        Map<String, Object> memory = new HashMap<>();
        memory.put("node_1.123", "7");

        String result = TextTemplate.of("{{node_1.123}}")
                .formatToString(Arrays.asList(memory, Collections.emptyMap()));

        Assert.assertEquals("7", result);
    }

    @Test
    public void shouldAllowResolvedEmptyStringWithoutTreatingItAsMissing() {
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("node_1.current", "");

        String result = TextTemplate.of("value={{node_1.current}}").formatToString(parameters);

        Assert.assertEquals("value=", result);
    }

    /**
     * 验证分层上下文保持后层覆盖前层的原有优先级。
     */
    @Test
    public void shouldResolveLayeredContextUsingLastMapPrecedence() {
        Map<String, Object> memory = new HashMap<>();
        memory.put("name", "memory");
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("name", "parameter");

        String result = TextTemplate.of("{{name}}")
                .formatToString(Arrays.asList(memory, parameters));

        Assert.assertEquals("parameter", result);
    }

    /**
     * 验证分层上下文支持跨层兜底并保持 JSON 转义。
     */
    @Test
    public void shouldResolveFallbackAcrossLayersWithJsonEscaping() {
        Map<String, Object> memory = new HashMap<>();
        memory.put("fallback", "a\"b");

        String result = TextTemplate.of("{\"value\":\"{{missing ?? fallback}}\"}")
                .formatToString(Arrays.asList(memory, Collections.emptyMap()), true);

        Assert.assertEquals("{\"value\":\"a\\\"b\"}", result);
    }

    /**
     * 后层拥有顶级键时，空对象应完整遮蔽前层同名对象。
     */
    @Test
    public void shouldPreservePutAllShadowingForNestedObject() {
        Map<String, Object> memory = new HashMap<>();
        memory.put("user", Collections.singletonMap("name", "legacy"));
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("user", Collections.emptyMap());

        String result = TextTemplate.of("{{user.name ?? \"fallback\"}}")
                .formatToString(Arrays.asList(memory, parameters));

        Assert.assertEquals("fallback", result);
    }

    /**
     * 后层显式 null 应遮蔽前层同名对象并进入模板兜底。
     */
    @Test
    public void shouldPreservePutAllShadowingForExplicitNull() {
        Map<String, Object> memory = new HashMap<>();
        memory.put("user", Collections.singletonMap("name", "legacy"));
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("user", null);

        String result = TextTemplate.of("{{user.name ?? \"fallback\"}}")
                .formatToString(Arrays.asList(memory, parameters));

        Assert.assertEquals("fallback", result);
    }
}
