package com.flowable.devops.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

import jakarta.persistence.*;
import java.time.LocalDateTime;

/**
 * 节点执行日志实体
 * 
 * 对应数据库表: node_execution_logs
 * 记录每个节点的详细执行情况，用于调试和监控
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "node_execution_logs")
@JsonIgnoreProperties(ignoreUnknown = true)
public class NodeExecutionLog {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    /**
     * 关联的工作流执行ID
     */
    @Column(name = "execution_id", nullable = false, length = 64)
    private String executionId;

    /**
     * 节点ID
     */
    @Column(name = "node_id", nullable = false, length = 64)
    private String nodeId;

    /**
     * 节点名称
     */
    @Column(name = "node_name")
    private String nodeName;

    /**
     * 节点类型
     */
    @Column(name = "node_type", length = 64)
    private String nodeType;

    /**
     * 节点输入参数
     */
    @JdbcTypeCode(SqlTypes.JSON)
    @Column(name = "input", columnDefinition = "JSON")
    private JsonNode input;

    /**
     * 节点输出结果
     */
    @JdbcTypeCode(SqlTypes.JSON)
    @Column(name = "output", columnDefinition = "JSON")
    private JsonNode output;

    /**
     * 执行状态：success, failed, skipped
     */
    @Column(name = "status", length = 20)
    @Enumerated(EnumType.STRING)
    private ExecutionStatus status;

    /**
     * 开始时间
     */
    @Column(name = "started_at")
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
    private LocalDateTime startedAt;

    /**
     * 结束时间
     */
    @Column(name = "ended_at")
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
    private LocalDateTime endedAt;

    /**
     * 执行耗时（毫秒）
     */
    @Column(name = "duration_ms")
    private Integer durationMs;

    /**
     * 错误信息
     */
    @Column(name = "error_message", columnDefinition = "TEXT")
    private String errorMessage;

    /**
     * 关联工作流执行记录
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "execution_id", insertable = false, updatable = false)
    private WorkflowExecution workflowExecution;

    /**
     * 执行状态枚举
     */
    public enum ExecutionStatus {
        SUCCESS("成功"),
        FAILED("失败"),
        SKIPPED("跳过");

        private final String description;

        ExecutionStatus(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }
    }

    /**
     * 计算执行耗时
     */
    @PrePersist
    @PreUpdate
    public void calculateDuration() {
        if (startedAt != null && endedAt != null) {
            this.durationMs = (int) java.time.Duration.between(startedAt, endedAt).toMillis();
        }
    }
}