package com.flowable.devops.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.flowable.devops.entity.NodeType;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

/**
 * NodeTypeService集成测试
 * 
 * 注意：不使用@Transactional，避免与数据初始化的事务隔离问题
 */
@SpringBootTest
@ActiveProfiles("test")
public class NodeTypeServiceTest {

    @Autowired
    private NodeTypeService nodeTypeService;
    
    @Autowired
    private ObjectMapper objectMapper;

    @Test
    public void testGetAllNodeTypes() {
        // 测试获取所有节点类型
        List<NodeType> nodeTypes = nodeTypeService.getAllNodeTypes();
        
        // 即使没有数据初始化，也要能正常返回（可能为空列表）
        assertNotNull(nodeTypes);
        
        // 如果有数据，验证基本结构
        if (!nodeTypes.isEmpty()) {
            // 验证节点类型基本属性不为空
            nodeTypes.forEach(nodeType -> {
                assertNotNull(nodeType.getId(), "节点类型ID不能为空");
                assertNotNull(nodeType.getName(), "节点类型名称不能为空");
                assertNotNull(nodeType.getCategory(), "节点类型分类不能为空");
            });
        }
    }

    @Test
    public void testCreateAndGetNodeType() throws Exception {
        // 创建测试节点类型
        NodeType testNodeType = new NodeType();
        testNodeType.setId("test-node");
        testNodeType.setName("测试节点");
        testNodeType.setDescription("用于测试的节点类型");
        testNodeType.setCategory(NodeType.NodeCategory.OTHER);
        testNodeType.setIcon("test-icon");
        testNodeType.setEnabled(true);
        testNodeType.setDisplayOrder(999);
        
        // 设置简单的字段定义
        String fieldsJson = "[{\"name\":\"testField\",\"type\":\"text\",\"required\":true}]";
        testNodeType.setFields(objectMapper.readTree(fieldsJson));
        
        // 设置输出模式
        String outputSchemaJson = "{\"type\":\"object\",\"properties\":{\"result\":{\"type\":\"string\"}}}";
        testNodeType.setOutputSchema(objectMapper.readTree(outputSchemaJson));
        
        // 创建节点类型
        NodeType created = nodeTypeService.createNodeType(testNodeType);
        
        assertNotNull(created);
        assertEquals("test-node", created.getId());
        assertEquals("测试节点", created.getName());
        assertEquals(NodeType.NodeCategory.OTHER, created.getCategory());
        assertTrue(created.isEnabled());
        assertNotNull(created.getCreatedAt());
        assertNotNull(created.getUpdatedAt());
        
        // 获取创建的节点类型
        NodeType retrieved = nodeTypeService.getNodeType("test-node");
        
        assertNotNull(retrieved);
        assertEquals(created.getId(), retrieved.getId());
        assertEquals(created.getName(), retrieved.getName());
        assertEquals(created.getCategory(), retrieved.getCategory());
    }

    @Test
    public void testGetCategories() {
        // 测试获取节点类型分类
        List<String> categories = nodeTypeService.getCategories();
        
        assertNotNull(categories);
        // 即使没有数据，也能正常返回空列表
        
        // 如果有分类数据，验证内容不为空
        categories.forEach(category -> {
            assertNotNull(category, "分类不能为空");
            assertFalse(category.trim().isEmpty(), "分类内容不能为空字符串");
        });
    }

    @Test
    public void testGetStatistics() {
        // 测试获取统计信息
        NodeTypeService.NodeTypeStatistics stats = nodeTypeService.getStatistics();
        
        assertNotNull(stats);
        assertTrue(stats.getTotalCount() >= 0, "总数量应该大于等于0");
        assertTrue(stats.getEnabledCount() >= 0, "启用数量应该大于等于0");
        assertTrue(stats.getDisabledCount() >= 0, "禁用数量应该大于等于0");
        assertEquals(stats.getTotalCount(), stats.getEnabledCount() + stats.getDisabledCount(), "总数 = 启用数 + 禁用数");
        
        assertNotNull(stats.getCategoryStats(), "分类统计不能为null");
        // 验证分类统计内容
        stats.getCategoryStats().forEach((category, count) -> {
            assertNotNull(category, "分类不能为null");
            assertTrue(count >= 0, "分类数量应该大于等于0");
        });
    }

    @Test
    public void testToggleEnabled() throws Exception {
        // 先创建一个测试节点
        NodeType testNodeType = new NodeType();
        testNodeType.setId("test-toggle-node");
        testNodeType.setName("测试切换节点");
        testNodeType.setDescription("用于测试启用/禁用的节点类型");
        testNodeType.setCategory(NodeType.NodeCategory.OTHER);
        testNodeType.setIcon("toggle-icon");
        testNodeType.setEnabled(true);
        
        String fieldsJson = "[]";
        testNodeType.setFields(objectMapper.readTree(fieldsJson));
        String outputSchemaJson = "{\"type\":\"object\"}";
        testNodeType.setOutputSchema(objectMapper.readTree(outputSchemaJson));
        
        NodeType created = nodeTypeService.createNodeType(testNodeType);
        assertTrue(created.isEnabled());
        
        // 禁用节点
        NodeType disabled = nodeTypeService.toggleEnabled("test-toggle-node", false);
        assertFalse(disabled.isEnabled());
        
        // 重新启用节点
        NodeType enabled = nodeTypeService.toggleEnabled("test-toggle-node", true);
        assertTrue(enabled.isEnabled());
    }
}