package com.easyagents.flow.core.test;

import com.easyagents.flow.core.chain.Chain;
import com.easyagents.flow.core.chain.ChainDefinition;
import com.easyagents.flow.core.chain.ChainStatus;
import com.easyagents.flow.core.chain.EventManager;
import com.easyagents.flow.core.chain.repository.InMemoryChainStateRepository;
import com.easyagents.flow.core.chain.repository.InMemoryNodeStateRepository;
import org.junit.Assert;
import org.junit.Test;

import java.util.Collections;
import java.util.Map;

/**
 * {@link Chain} 暂停恢复状态守卫测试。
 */
public class ChainResumeGuardTest {

    /**
     * 验证只有暂停中的实例可以恢复，重复恢复不会再次注入变量。
     */
    @Test
    public void shouldResumeOnlyOnceFromSuspendedState() {
        InMemoryChainStateRepository stateRepository =
                new InMemoryChainStateRepository();
        Chain chain = createChain(stateRepository, "resume-once");
        chain.suspend();

        boolean resumed = chain.resumeIfSuspended(
                Map.of("approved", true));
        boolean resumedAgain = chain.resumeIfSuspended(
                Map.of("unexpected", true));

        Assert.assertTrue(resumed);
        Assert.assertFalse(resumedAgain);
        Assert.assertEquals(
                ChainStatus.RUNNING,
                stateRepository.load("resume-once").getStatus());
        Assert.assertEquals(
                Boolean.TRUE,
                stateRepository.load("resume-once")
                        .getMemory()
                        .get("approved"));
        Assert.assertFalse(
                stateRepository.load("resume-once")
                        .getMemory()
                        .containsKey("unexpected"));
    }

    /**
     * 验证成功终态不会被恢复操作改回运行中。
     */
    @Test
    public void shouldKeepTerminalStateUnchanged() {
        InMemoryChainStateRepository stateRepository =
                new InMemoryChainStateRepository();
        Chain chain = createChain(stateRepository, "resume-terminal");
        stateRepository.load("resume-terminal")
                .setStatus(ChainStatus.SUCCEEDED);

        boolean resumed = chain.resumeIfSuspended(
                Map.of("unexpected", true));

        Assert.assertFalse(resumed);
        Assert.assertEquals(
                ChainStatus.SUCCEEDED,
                stateRepository.load("resume-terminal").getStatus());
        Assert.assertFalse(
                stateRepository.load("resume-terminal")
                        .getMemory()
                        .containsKey("unexpected"));
    }

    /**
     * 创建使用进程内状态仓储的最小工作流。
     *
     * @param stateRepository 状态仓储
     * @param instanceId 工作流实例 ID
     * @return 已配置工作流
     */
    private Chain createChain(
            InMemoryChainStateRepository stateRepository,
            String instanceId) {
        ChainDefinition definition = new ChainDefinition();
        definition.setId("resume-definition");
        definition.setNodes(Collections.emptyList());
        definition.setEdges(Collections.emptyList());
        Chain chain = new Chain(definition, instanceId);
        chain.setChainStateRepository(stateRepository);
        chain.setNodeStateRepository(
                new InMemoryNodeStateRepository());
        chain.setEventManager(new EventManager());
        return chain;
    }
}
