package com.easyagents.federation.sql.compile;

import com.easyagents.federation.sql.execute.FederationColumn;
import com.easyagents.federation.sql.execute.FederationPhysicalExplain;
import com.easyagents.federation.sql.federation.FederationCostEstimate;
import com.easyagents.federation.sql.source.SourceId;
import java.io.Serializable;
import java.util.List;

/**
 * Explain 中一个目标数据库分片的纯数据视图。
 *
 * @param fragmentId 分片标识
 * @param bindingName 查询范围 Binding 名称
 * @param sourceId 物理数据源
 * @param adapterId Adapter 标识
 * @param executableSql 目标方言参数化 SQL
 * @param parameterMapping 分片参数到原查询参数的映射
 * @param columns 分片输出列
 * @param costEstimate 分片搬运成本估算
 * @param pushedDownOperators 已下推算子
 * @param physicalExplain 显式物理 Explain；逻辑级别时为空
 */
public record FederationFragmentExplain(
    String fragmentId,
    String bindingName,
    SourceId sourceId,
    String adapterId,
    String executableSql,
    List<Integer> parameterMapping,
    List<FederationColumn> columns,
    FederationCostEstimate costEstimate,
    List<String> pushedDownOperators,
    FederationPhysicalExplain physicalExplain
) implements Serializable {

    /**
     * 防御性复制集合字段。
     */
    public FederationFragmentExplain {
        parameterMapping = List.copyOf(parameterMapping == null ? List.of() : parameterMapping);
        columns = List.copyOf(columns == null ? List.of() : columns);
        pushedDownOperators = List.copyOf(
            pushedDownOperators == null ? List.of() : pushedDownOperators
        );
    }

    /**
     * 创建旧字段集合的兼容 Explain 分片。
     *
     * @param fragmentId 分片标识
     * @param bindingName Binding 名称
     * @param sourceId 物理源
     * @param adapterId Adapter 标识
     * @param executableSql 目标 SQL
     * @param parameterMapping 参数映射
     * @param columns 输出列
     * @param physicalExplain 物理 Explain
     */
    public FederationFragmentExplain(
        String fragmentId,
        String bindingName,
        SourceId sourceId,
        String adapterId,
        String executableSql,
        List<Integer> parameterMapping,
        List<FederationColumn> columns,
        FederationPhysicalExplain physicalExplain
    ) {
        this(
            fragmentId,
            bindingName,
            sourceId,
            adapterId,
            executableSql,
            parameterMapping,
            columns,
            new FederationCostEstimate(
                0,
                0,
                0,
                "calcite-default",
                "none",
                java.time.Instant.EPOCH,
                true,
                com.easyagents.federation.sql.federation.FederationStatisticsStatus.MISSING,
                false
            ),
            List.of(),
            physicalExplain
        );
    }
}
