package com.easyagents.federation.sql.compile;

import com.easyagents.federation.sql.federation.FederationQueryScopeDefinition;
import com.easyagents.federation.sql.federation.FederationSourceBindingDefinition;
import com.easyagents.federation.sql.source.SourceId;
import java.util.List;

/**
 * 节点本地 SQL 编译请求。
 *
 * @param sql 单条只读 SQL
 * @param queryScope 查询可见的数据源范围
 * @param parameterJdbcTypes 参数 JDBC 类型列表
 * @param policyVersion 调用方策略版本，用于隔离计划缓存
 */
public record SqlCompileRequest(
    String sql,
    FederationQueryScopeDefinition queryScope,
    List<Integer> parameterJdbcTypes,
    String policyVersion
) {

    /**
     * 校验并防御性复制编译请求。
     */
    public SqlCompileRequest {
        if (sql == null || sql.isBlank()) {
            throw new IllegalArgumentException("sql must not be blank");
        }
        if (queryScope == null) {
            throw new IllegalArgumentException("queryScope must not be null");
        }
        parameterJdbcTypes = List.copyOf(parameterJdbcTypes == null ? List.of() : parameterJdbcTypes);
        policyVersion = policyVersion == null || policyVersion.isBlank() ? "default" : policyVersion;
    }

    /**
     * 使用单物理数据源创建兼容编译请求。
     *
     * @param sql 单条只读 SQL
     * @param sourceId 默认数据源
     * @param minimumRevision 最低数据源版本
     * @param parameterJdbcTypes 参数 JDBC 类型
     * @param policyVersion 调用方策略版本
     */
    public SqlCompileRequest(
        String sql,
        SourceId sourceId,
        long minimumRevision,
        List<Integer> parameterJdbcTypes,
        String policyVersion
    ) {
        this(
            sql,
            FederationQueryScopeDefinition.single(sourceId, minimumRevision),
            parameterJdbcTypes,
            policyVersion
        );
    }

    /**
     * 返回默认 Binding 的物理数据源，供单源调用方兼容读取。
     *
     * @return 默认物理数据源
     */
    public SourceId sourceId() {
        return defaultBinding().sourceId();
    }

    /**
     * 返回默认 Binding 的最低物理 Definition 版本。
     *
     * @return 最低版本
     */
    public long minimumRevision() {
        return defaultBinding().minimumRevision();
    }

    private FederationSourceBindingDefinition defaultBinding() {
        return queryScope.defaultBindingDefinition();
    }

    /**
     * 创建无参数的默认编译请求。
     *
     * @param sql 单条只读 SQL
     * @param sourceId 默认数据源
     * @param minimumRevision 最低数据源版本
     * @return 编译请求
     */
    public static SqlCompileRequest of(String sql, SourceId sourceId, long minimumRevision) {
        return new SqlCompileRequest(sql, sourceId, minimumRevision, List.of(), "default");
    }

    /**
     * 创建无参数的查询范围编译请求。
     *
     * @param sql 单条只读 SQL
     * @param queryScope 查询范围
     * @return 编译请求
     */
    public static SqlCompileRequest of(
        String sql,
        FederationQueryScopeDefinition queryScope
    ) {
        return new SqlCompileRequest(sql, queryScope, List.of(), "default");
    }
}
