package com.flowable.devops.repository;

import com.flowable.devops.entity.NodeExecutionLog;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 节点执行日志数据访问接口
 */
@Repository
public interface NodeExecutionLogRepository extends JpaRepository<NodeExecutionLog, Long> {

    /**
     * 根据执行ID查询节点日志
     */
    List<NodeExecutionLog> findByExecutionIdOrderByStartedAt(String executionId);

    /**
     * 根据节点ID查询日志
     */
    List<NodeExecutionLog> findByNodeIdOrderByStartedAtDesc(String nodeId);

    /**
     * 根据节点类型查询日志
     */
    List<NodeExecutionLog> findByNodeTypeOrderByStartedAtDesc(String nodeType);

    /**
     * 根据执行状态查询
     */
    List<NodeExecutionLog> findByStatus(NodeExecutionLog.ExecutionStatus status);

    /**
     * 根据执行ID和节点ID查询（唯一记录）
     */
    List<NodeExecutionLog> findByExecutionIdAndNodeId(String executionId, String nodeId);

    /**
     * 查询失败的节点执行日志
     */
    @Query("SELECT n FROM NodeExecutionLog n WHERE n.status = 'FAILED' ORDER BY n.startedAt DESC")
    List<NodeExecutionLog> findFailedExecutions();

    /**
     * 查询指定时间范围内的节点执行日志
     */
    @Query("SELECT n FROM NodeExecutionLog n WHERE n.startedAt BETWEEN :startTime AND :endTime ORDER BY n.startedAt DESC")
    List<NodeExecutionLog> findByStartedAtBetween(
        @Param("startTime") LocalDateTime startTime,
        @Param("endTime") LocalDateTime endTime
    );

    /**
     * 统计各状态的节点执行数量
     */
    @Query("SELECT n.status, COUNT(n) FROM NodeExecutionLog n GROUP BY n.status")
    List<Object[]> countByStatus();

    /**
     * 统计各节点类型的执行数量
     */
    @Query("SELECT n.nodeType, COUNT(n) FROM NodeExecutionLog n GROUP BY n.nodeType ORDER BY COUNT(n) DESC")
    List<Object[]> countByNodeType();

    /**
     * 查询平均执行时长
     */
    @Query("SELECT AVG(n.durationMs) FROM NodeExecutionLog n WHERE n.status = 'SUCCESS' AND n.durationMs IS NOT NULL")
    Double findAverageExecutionTime();

    /**
     * 查询指定节点类型的平均执行时长
     */
    @Query("SELECT AVG(n.durationMs) FROM NodeExecutionLog n WHERE n.nodeType = :nodeType AND n.status = 'SUCCESS' AND n.durationMs IS NOT NULL")
    Double findAverageExecutionTimeByNodeType(@Param("nodeType") String nodeType);

    /**
     * 查询最慢的节点执行记录
     */
    @Query("SELECT n FROM NodeExecutionLog n WHERE n.status = 'SUCCESS' AND n.durationMs IS NOT NULL ORDER BY n.durationMs DESC")
    List<NodeExecutionLog> findSlowestExecutions();

    /**
     * 根据执行ID查询执行统计
     */
    @Query("SELECT n.status, COUNT(n), AVG(n.durationMs) FROM NodeExecutionLog n WHERE n.executionId = :executionId GROUP BY n.status")
    List<Object[]> findExecutionStatistics(@Param("executionId") String executionId);

    /**
     * 删除指定时间之前的日志（清理历史数据）
     */
    @Query("DELETE FROM NodeExecutionLog n WHERE n.startedAt < :cutoffTime")
    void deleteLogsBefore(@Param("cutoffTime") LocalDateTime cutoffTime);

    /**
     * 查询指定执行中失败的节点
     */
    @Query("SELECT n FROM NodeExecutionLog n WHERE n.executionId = :executionId AND n.status = 'FAILED'")
    List<NodeExecutionLog> findFailedNodesByExecution(@Param("executionId") String executionId);
}