package tech.easyflow.publicapi.service;

import com.easyagents.flow.core.chain.ChainStatus;
import com.easyagents.flow.core.chain.NodeStatus;
import org.junit.Assert;
import org.junit.Test;
import tech.easyflow.ai.easyagentsflow.entity.ChainInfo;
import tech.easyflow.ai.easyagentsflow.entity.NodeInfo;
import tech.easyflow.publicapi.dto.PublicWorkflowChainStatus;
import tech.easyflow.publicapi.dto.PublicWorkflowExecutionStatus;

import java.util.Map;

/**
 * {@link PublicWorkflowStatusSanitizer} 公共错误脱敏测试。
 */
public class PublicWorkflowStatusSanitizerTest {

    private final PublicWorkflowStatusSanitizer sanitizer =
            new PublicWorkflowStatusSanitizer();

    /**
     * 验证内部异常类名和依赖详情不会进入公共状态。
     */
    @Test
    public void shouldHideInternalExecutionErrorDetails() {
        ChainInfo source = new ChainInfo();
        source.setExecuteId("execute-1");
        source.setStatus(ChainStatus.FAILED.getValue());
        source.setMessage(
                "io.minio.errors.ErrorResponseException --> signature mismatch at http://internal:9000");
        NodeInfo node = new NodeInfo();
        node.setNodeId("node-1");
        node.setNodeName("文档解析");
        node.setStatus(NodeStatus.FAILED.getValue());
        node.setMessage("java.lang.IllegalStateException --> bucket-secret");
        source.setNodes(Map.of("node-1", node));

        PublicWorkflowChainStatus result = sanitizer.sanitize(source);

        Assert.assertEquals(
                "工作流执行失败，请检查输入或稍后重试",
                result.message());
        Assert.assertFalse(result.message().contains("minio"));
        Assert.assertEquals(
                "节点执行失败，请检查输入或稍后重试",
                result.nodes().get("node-1").message());
        Assert.assertEquals("node-1", result.error().getNodeId());
        Assert.assertFalse(result.error().isRetryable());
        Assert.assertEquals(
                PublicWorkflowExecutionStatus.FAILED,
                result.status());
        Assert.assertTrue(result.terminal());
    }

    /**
     * 验证成功状态保持原有响应且不增加错误对象。
     */
    @Test
    public void shouldKeepSuccessfulStatusWithoutError() {
        ChainInfo source = new ChainInfo();
        source.setExecuteId("execute-1");
        source.setStatus(ChainStatus.SUCCEEDED.getValue());
        source.setResult(Map.of("output", "ok"));

        PublicWorkflowChainStatus result = sanitizer.sanitize(source);

        Assert.assertEquals(source.getResult(), result.result());
        Assert.assertEquals(
                PublicWorkflowExecutionStatus.DONE,
                result.status());
        Assert.assertTrue(result.terminal());
        Assert.assertNull(result.message());
        Assert.assertNull(result.error());
    }

    /**
     * 验证节点名称保持不变，并将节点状态转换为可读枚举。
     */
    @Test
    public void shouldKeepNodeNameAndReadableStatus() {
        ChainInfo source = new ChainInfo();
        source.setExecuteId("execute-1");
        source.setStatus(ChainStatus.RUNNING.getValue());
        NodeInfo node = new NodeInfo();
        node.setNodeId("node-1");
        node.setNodeName("文档解析");
        node.setStatus(NodeStatus.RUNNING.getValue());
        source.setNodes(Map.of("node-1", node));

        PublicWorkflowChainStatus result = sanitizer.sanitize(source);

        Assert.assertEquals(
                PublicWorkflowExecutionStatus.RUNNING,
                result.status());
        Assert.assertFalse(result.terminal());
        Assert.assertEquals(
                "文档解析",
                result.nodes().get("node-1").nodeName());
        Assert.assertEquals(
                PublicWorkflowExecutionStatus.RUNNING,
                result.nodes().get("node-1").status());
    }
}
