package com.flowable.devops.workflow.node;

import com.flowable.devops.entity.NodeType;
import com.flowable.devops.workflow.model.NodeExecutionContext;
import com.flowable.devops.workflow.model.NodeExecutionResult;
import com.flowable.devops.workflow.model.NodeInput;

/**
 * 工作流节点接口
 * <p>
 * 所有工作流节点必须实现此接口
 * <p>
 * 设计原则：
 * 1. 节点应该是无状态的，所有状态通过参数传递
 * 2. 节点应该是幂等的，多次执行相同输入应得到相同结果
 * 3. 节点应该处理自己的错误，不应该让未处理的异常向上抛出
 * 4. 节点应该提供详细的元数据，支持前端动态渲染
 */
public interface WorkflowNode {

    /**
     * 获取节点元数据
     * <p>
     * 包含节点的字段定义、输出结构、分类等信息
     * 前端根据此信息动态生成表单和字段映射
     *
     * @return 节点类型元数据
     */
    NodeType getMetadata();

    /**
     * 执行节点
     *
     * @param input   节点输入参数（表达式已解析）
     * @param context 执行上下文，包含工作流变量、环境变量等
     * @return 节点执行结果
     */
    NodeExecutionResult execute(NodeInput input, NodeExecutionContext context);

    /**
     * 验证节点配置
     * <p>
     * 在节点执行前验证配置是否正确
     * 可选实现，默认不做验证
     *
     * @param input 节点输入参数
     * @throws IllegalArgumentException 如果配置无效
     */
    default void validate(NodeInput input) {
        // 默认实现：不做验证
    }

    /**
     * 获取节点类型ID
     * <p>
     * 便捷方法，等价于 getMetadata().getId()
     *
     * @return 节点类型ID
     */
    default String getNodeTypeId() {
        NodeType metadata = getMetadata();
        return metadata != null ? metadata.getId() : null;
    }

    /**
     * 获取节点显示名称
     * <p>
     * 便捷方法，等价于 getMetadata().getDisplayName()
     *
     * @return 节点显示名称
     */
    default String getDisplayName() {
        NodeType metadata = getMetadata();
        return metadata != null ? metadata.getDisplayName() : null;
    }

    /**
     * 检查节点是否支持指定的配置参数
     *
     * @param parameterName 参数名称
     * @return 是否支持该参数
     */
    default boolean supportsParameter(String parameterName) {
        NodeType metadata = getMetadata();
        if (metadata == null || metadata.getFields() == null) {
            return false;
        }

        // 这里需要解析 fields JSON，简化实现返回 true
        // 实际实现中应该检查字段定义
        return true;
    }
}