package com.flowable.devops.workflow.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 节点执行结果模型
 * 
 * 封装节点执行的结果信息
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class NodeExecutionResult {
    
    /**
     * 执行状态
     */
    private ExecutionStatus status;
    
    /**
     * 输出数据
     */
    private Map<String, Object> output;
    
    /**
     * 错误信息
     */
    private String error;
    
    /**
     * 错误类型
     */
    private String errorType;
    
    /**
     * 开始时间
     */
    private LocalDateTime startTime;
    
    /**
     * 结束时间
     */
    private LocalDateTime endTime;
    
    /**
     * 执行耗时（毫秒）
     */
    private Long durationMs;
    
    /**
     * 执行状态枚举
     */
    public enum ExecutionStatus {
        SUCCESS,
        FAILED,
        SKIPPED
    }
    
    /**
     * 创建成功结果
     */
    public static NodeExecutionResult success(Map<String, Object> output, LocalDateTime startTime, LocalDateTime endTime) {
        long duration = java.time.Duration.between(startTime, endTime).toMillis();
        return NodeExecutionResult.builder()
                .status(ExecutionStatus.SUCCESS)
                .output(output != null ? new HashMap<>(output) : new HashMap<>())
                .startTime(startTime)
                .endTime(endTime)
                .durationMs(duration)
                .build();
    }
    
    /**
     * 创建失败结果
     */
    public static NodeExecutionResult failed(String error, String errorType, LocalDateTime startTime, LocalDateTime endTime) {
        long duration = java.time.Duration.between(startTime, endTime).toMillis();
        return NodeExecutionResult.builder()
                .status(ExecutionStatus.FAILED)
                .output(new HashMap<>())
                .error(error)
                .errorType(errorType)
                .startTime(startTime)
                .endTime(endTime)
                .durationMs(duration)
                .build();
    }
    
    /**
     * 创建跳过结果
     */
    public static NodeExecutionResult skipped(String reason, LocalDateTime startTime, LocalDateTime endTime) {
        return NodeExecutionResult.builder()
                .status(ExecutionStatus.SKIPPED)
                .output(new HashMap<>())
                .error(reason)
                .startTime(startTime)
                .endTime(endTime)
                .durationMs(0L)
                .build();
    }
    
    /**
     * 检查执行是否成功
     */
    public boolean isSuccess() {
        return status == ExecutionStatus.SUCCESS;
    }
    
    /**
     * 检查执行是否失败
     */
    public boolean isFailed() {
        return status == ExecutionStatus.FAILED;
    }
    
    /**
     * 检查执行是否跳过
     */
    public boolean isSkipped() {
        return status == ExecutionStatus.SKIPPED;
    }
    
    /**
     * 获取输出值
     */
    public Object getOutputValue(String key) {
        return output != null ? output.get(key) : null;
    }
    
    /**
     * 添加输出值
     */
    public void addOutput(String key, Object value) {
        if (output == null) {
            output = new HashMap<>();
        }
        output.put(key, value);
    }
    
    /**
     * 计算执行耗时
     */
    public long calculateDuration() {
        if (startTime != null && endTime != null) {
            return java.time.Duration.between(startTime, endTime).toMillis();
        }
        return 0;
    }
}