package com.easyagents.flow.core.test;

import com.alibaba.fastjson.JSONObject;
import com.easyagents.flow.core.chain.DataType;
import com.easyagents.flow.core.node.LoopNode;
import com.easyagents.flow.core.parser.impl.LoopNodeParser;
import org.junit.Assert;
import org.junit.Test;

/**
 * 验证循环节点新旧输入结构的解析兼容。
 */
public class LoopNodeParserTest {

    /**
     * 验证新结构可以同时解析循环次数和输入数组。
     */
    @Test
    public void shouldParseExplicitLoopInputs() {
        JSONObject count = parameter(
                "count", "Number", "fixed", null, "3");
        JSONObject items = parameter(
                "items", "Array<Object>", "ref",
                "knowledge.documents", null);
        JSONObject loopInputs = new JSONObject();
        loopInputs.put("count", count);
        loopInputs.put("items", items);
        JSONObject data = new JSONObject();
        data.put("loopInputs", loopInputs);

        LoopNode loopNode = new LoopNodeParser().doParse(
                new JSONObject(), data, new JSONObject());

        Assert.assertNotNull(loopNode.getLoopCount());
        Assert.assertEquals(
                DataType.Number,
                loopNode.getLoopCount().getDataType());
        Assert.assertEquals(
                "3", loopNode.getLoopCount().getValue());
        Assert.assertNotNull(loopNode.getLoopItems());
        Assert.assertEquals(
                DataType.Array_Object,
                loopNode.getLoopItems().getDataType());
        Assert.assertEquals(
                "knowledge.documents",
                loopNode.getLoopItems().getRef());
        Assert.assertNull(loopNode.getLoopVar());
    }

    /**
     * 验证旧版 loopVars 第一项继续映射为兼容参数。
     */
    @Test
    public void shouldParseLegacyLoopVar() {
        com.alibaba.fastjson.JSONArray loopVars =
                new com.alibaba.fastjson.JSONArray();
        loopVars.add(parameter(
                "loopVar", "Number", "fixed", null, "2"));
        JSONObject data = new JSONObject();
        data.put("loopVars", loopVars);

        LoopNode loopNode = new LoopNodeParser().doParse(
                new JSONObject(), data, new JSONObject());

        Assert.assertNotNull(loopNode.getLoopVar());
        Assert.assertEquals("2", loopNode.getLoopVar().getValue());
        Assert.assertNull(loopNode.getLoopCount());
        Assert.assertNull(loopNode.getLoopItems());
    }

    /**
     * 验证循环输出可以解析扁平聚合配置。
     */
    @Test
    public void shouldParseFlattenAggregationFromOutputDefinition() {
        JSONObject data = new JSONObject();
        com.alibaba.fastjson.JSONArray outputDefs =
                new com.alibaba.fastjson.JSONArray();
        JSONObject output = parameter(
                "res",
                "Array<String>",
                "ref",
                "knowledge.documents.content",
                null);
        output.put("flattenAggregation", true);
        outputDefs.add(output);
        data.put("outputDefs", outputDefs);
        JSONObject nodeJson = new JSONObject();
        nodeJson.put("id", "loop");
        nodeJson.put("type", "loopNode");
        nodeJson.put("data", data);

        LoopNode loopNode = new LoopNodeParser().parse(
                nodeJson, new JSONObject(), null);

        Assert.assertEquals(1, loopNode.getOutputDefs().size());
        Assert.assertTrue(
                loopNode.getOutputDefs().get(0).isFlattenAggregation());
    }

    /**
     * 构造参数 JSON。
     *
     * @param name 参数名
     * @param dataType 数据类型
     * @param refType 引用类型
     * @param ref 引用路径
     * @param value 固定值
     * @return 参数 JSON
     */
    private static JSONObject parameter(
            String name,
            String dataType,
            String refType,
            String ref,
            String value) {
        JSONObject parameter = new JSONObject();
        parameter.put("name", name);
        parameter.put("dataType", dataType);
        parameter.put("refType", refType);
        parameter.put("ref", ref);
        parameter.put("value", value);
        return parameter;
    }
}
