package com.easyagents.federation.sql.federation;

import java.io.Serializable;
import java.time.Instant;

/**
 * 一个物理分片的轻量搬运成本估算。
 *
 * @param estimatedRows 分片输出估算行数
 * @param estimatedRowWidthBytes 分片输出估算行宽
 * @param estimatedTransferBytes 分片到本地执行器的估算搬运字节数
 * @param statisticsSource 统计来源
 * @param statisticsSnapshotVersion 统计快照版本
 * @param statisticsCollectedAt 外部统计采集时间；缺失时为 epoch
 * @param statisticsMissing 是否完全使用 Calcite 默认估算
 * @param statisticsStatus 统计完整性与时效状态
 * @param estimateAvailable 当前数值是否为有效估算；兼容旧计划缺少估算时为 false
 */
public record FederationCostEstimate(
    double estimatedRows,
    long estimatedRowWidthBytes,
    double estimatedTransferBytes,
    String statisticsSource,
    String statisticsSnapshotVersion,
    Instant statisticsCollectedAt,
    boolean statisticsMissing,
    FederationStatisticsStatus statisticsStatus,
    boolean estimateAvailable
) implements Serializable {

    /**
     * 校验并规范化成本估算。
     */
    public FederationCostEstimate {
        if (!Double.isFinite(estimatedRows) || estimatedRows < 0
            || estimatedRowWidthBytes < 0
            || !Double.isFinite(estimatedTransferBytes)
            || estimatedTransferBytes < 0) {
            throw new IllegalArgumentException("cost estimate values must be finite and non-negative");
        }
        statisticsSource = statisticsSource == null || statisticsSource.isBlank()
            ? "calcite-default"
            : statisticsSource;
        statisticsSnapshotVersion = statisticsSnapshotVersion == null
            ? "none"
            : statisticsSnapshotVersion;
        statisticsCollectedAt = statisticsCollectedAt == null
            ? Instant.EPOCH
            : statisticsCollectedAt;
        statisticsStatus = statisticsStatus == null
            ? statisticsMissing
                ? FederationStatisticsStatus.MISSING
                : FederationStatisticsStatus.COMPLETE
            : statisticsStatus;
    }

    /**
     * 创建带显式统计状态的有效成本估算。
     *
     * @param estimatedRows 估算行数
     * @param estimatedRowWidthBytes 估算行宽
     * @param estimatedTransferBytes 估算搬运字节
     * @param statisticsSource 统计来源
     * @param statisticsSnapshotVersion 统计版本
     * @param statisticsCollectedAt 采集时间
     * @param statisticsMissing 是否缺失统计
     * @param statisticsStatus 统计状态
     */
    public FederationCostEstimate(
        double estimatedRows,
        long estimatedRowWidthBytes,
        double estimatedTransferBytes,
        String statisticsSource,
        String statisticsSnapshotVersion,
        Instant statisticsCollectedAt,
        boolean statisticsMissing,
        FederationStatisticsStatus statisticsStatus
    ) {
        this(
            estimatedRows,
            estimatedRowWidthBytes,
            estimatedTransferBytes,
            statisticsSource,
            statisticsSnapshotVersion,
            statisticsCollectedAt,
            statisticsMissing,
            statisticsStatus,
            true
        );
    }

    /**
     * 创建旧字段集合的兼容成本估算。
     *
     * @param estimatedRows 估算行数
     * @param estimatedRowWidthBytes 估算行宽
     * @param estimatedTransferBytes 估算搬运字节
     * @param statisticsSource 统计来源
     * @param statisticsSnapshotVersion 统计版本
     * @param statisticsCollectedAt 采集时间
     * @param statisticsMissing 是否缺失统计
     */
    public FederationCostEstimate(
        double estimatedRows,
        long estimatedRowWidthBytes,
        double estimatedTransferBytes,
        String statisticsSource,
        String statisticsSnapshotVersion,
        Instant statisticsCollectedAt,
        boolean statisticsMissing
    ) {
        this(
            estimatedRows,
            estimatedRowWidthBytes,
            estimatedTransferBytes,
            statisticsSource,
            statisticsSnapshotVersion,
            statisticsCollectedAt,
            statisticsMissing,
            statisticsMissing
                ? FederationStatisticsStatus.MISSING
                : FederationStatisticsStatus.COMPLETE,
            true
        );
    }
}
