package tech.easyflow.agent.service.impl;

import org.junit.Assert;
import org.junit.Test;
import tech.easyflow.agent.entity.AgentKnowledgeBinding;
import tech.easyflow.agent.entity.AgentSkillBinding;
import tech.easyflow.agent.entity.AgentToolBinding;

import java.math.BigInteger;
import java.util.List;
import java.util.Map;

/**
 * Agent 绑定业务字段比较测试。
 */
public class AgentBindingSemanticComparatorTest {

    /**
     * 验证工具绑定忽略 ID 与审计字段，并识别真实配置变化。
     */
    @Test
    public void toolsShouldCompareOnlyPersistedBusinessFields() {
        AgentToolBinding persisted = toolBinding();
        persisted.setId(BigInteger.valueOf(99));
        AgentToolBinding requested = toolBinding();

        Assert.assertTrue(AgentBindingSemanticComparator.sameTools(
                List.of(persisted), List.of(requested)));

        requested.setHitlEnabled(true);
        Assert.assertFalse(AgentBindingSemanticComparator.sameTools(
                List.of(persisted), List.of(requested)));
    }

    /**
     * 验证知识库默认检索模式与默认启用状态保持幂等。
     */
    @Test
    public void knowledgesShouldNormalizeDefaultsBeforeComparison() {
        AgentKnowledgeBinding persisted = new AgentKnowledgeBinding();
        persisted.setKnowledgeId(BigInteger.TEN);
        persisted.setRetrievalMode("HYBRID");
        persisted.setEnabled(true);
        persisted.setOptionsJson(Map.of("limit", 5));
        persisted.setSortNo(0);

        AgentKnowledgeBinding requested = new AgentKnowledgeBinding();
        requested.setKnowledgeId(BigInteger.TEN);
        requested.setOptionsJson(Map.of("limit", 5));

        Assert.assertTrue(AgentBindingSemanticComparator.sameKnowledges(
                List.of(persisted), List.of(requested)));
    }

    /**
     * 验证 Skill 顺序变化会触发替换。
     */
    @Test
    public void skillsShouldDetectOrderChanges() {
        AgentSkillBinding first = skillBinding(1, 0);
        AgentSkillBinding second = skillBinding(2, 1);

        Assert.assertTrue(AgentBindingSemanticComparator.sameSkills(
                List.of(first, second),
                List.of(skillBinding(1, null), skillBinding(2, null))));
        Assert.assertFalse(AgentBindingSemanticComparator.sameSkills(
                List.of(first, second),
                List.of(skillBinding(2, null), skillBinding(1, null))));
    }

    private AgentToolBinding toolBinding() {
        AgentToolBinding binding = new AgentToolBinding();
        binding.setToolType("PLUGIN");
        binding.setTargetId(BigInteger.ONE);
        binding.setToolName("lookup");
        binding.setEnabled(true);
        binding.setHitlEnabled(false);
        binding.setHitlConfigJson(Map.of());
        binding.setOptionsJson(Map.of("executionMode", "SYNC"));
        binding.setSortNo(0);
        return binding;
    }

    private AgentSkillBinding skillBinding(long id, Integer sortNo) {
        AgentSkillBinding binding = new AgentSkillBinding();
        binding.setSkillId(BigInteger.valueOf(id));
        binding.setSortNo(sortNo);
        return binding;
    }
}
