package tech.easyflow.agent.publish;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Assert;
import org.junit.Test;
import tech.easyflow.agent.service.AgentKnowledgeBindingService;
import tech.easyflow.agent.service.AgentToolBindingService;

import java.lang.reflect.Proxy;
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * {@link AgentApprovalSubjectHandler} 单元测试。
 */
public class AgentApprovalSubjectHandlerTest {

    /**
     * 审批删除 Agent 前必须同步清理工具绑定和知识库绑定，避免留下孤儿数据。
     */
    @Test
    public void beforeRemoveShouldCleanAgentBindings() {
        AtomicInteger toolRemoveCalls = new AtomicInteger();
        AtomicInteger knowledgeRemoveCalls = new AtomicInteger();
        AgentToolBindingService toolBindingService = proxy(AgentToolBindingService.class, toolRemoveCalls);
        AgentKnowledgeBindingService knowledgeBindingService = proxy(AgentKnowledgeBindingService.class, knowledgeRemoveCalls);
        AgentApprovalSubjectHandler handler = new AgentApprovalSubjectHandler(
                null,
                new ObjectMapper(),
                null,
                toolBindingService,
                knowledgeBindingService,
                null
        );

        handler.beforeRemove(BigInteger.valueOf(1001));

        Assert.assertEquals(1, toolRemoveCalls.get());
        Assert.assertEquals(1, knowledgeRemoveCalls.get());
    }

    @SuppressWarnings("unchecked")
    private static <T> T proxy(Class<T> type, AtomicInteger removeCalls) {
        return (T) Proxy.newProxyInstance(
                type.getClassLoader(),
                new Class<?>[]{type},
                (proxy, method, args) -> {
                    if ("remove".equals(method.getName()) && args != null && args.length == 1) {
                        removeCalls.incrementAndGet();
                        return true;
                    }
                    if (method.getReturnType() == boolean.class || method.getReturnType() == Boolean.class) {
                        return false;
                    }
                    return null;
                }
        );
    }
}
