package com.easyagents.federation.sql.execute;

import com.easyagents.federation.sql.adapter.AdapterCompatibility;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;

/**
 * 单数据源 SQL Fragment 的执行上下文。
 *
 * @param queryId 查询标识
 * @param sql 已按目标方言生成的参数化 SQL
 * @param parameters JDBC 参数
 * @param options 强制执行限制
 * @param dataSource 调用方提供的 DataSource
 * @param compatibility 当前数据库与驱动兼容性信息
 * @param adapterOptions 不含凭据的 Adapter 执行选项
 * @param statementLifecycle Statement 取消登记回调
 * @param observer Fragment 执行阶段观察器
 * @param executionGuard 查询取消与统一截止时间检查器
 */
public record FederationFragmentExecutionContext(
    QueryId queryId,
    String sql,
    List<SqlParameter> parameters,
    SqlExecutionOptions options,
    DataSource dataSource,
    AdapterCompatibility compatibility,
    Map<String, String> adapterOptions,
    StatementLifecycle statementLifecycle,
    FederationExecutionObserver observer,
    FederationExecutionGuard executionGuard
) {

    /**
     * 防御性复制参数并校验必需字段。
     */
    public FederationFragmentExecutionContext {
        if (queryId == null || sql == null || sql.isBlank() || options == null
            || dataSource == null || compatibility == null || statementLifecycle == null) {
            throw new IllegalArgumentException("fragment execution context contains null or blank values");
        }
        parameters = List.copyOf(parameters == null ? List.of() : parameters);
        adapterOptions = Map.copyOf(adapterOptions == null ? Map.of() : adapterOptions);
        observer = observer == null ? FederationExecutionObserver.none() : observer;
        executionGuard = executionGuard == null ? FederationExecutionGuard.none() : executionGuard;
    }

    /**
     * 创建不采集 Adapter 阶段指标的兼容执行上下文。
     *
     * @param queryId 查询标识
     * @param sql 参数化 SQL
     * @param parameters JDBC 参数
     * @param options 执行限制
     * @param dataSource 数据源
     * @param compatibility 数据库兼容信息
     * @param adapterOptions Adapter 选项
     * @param statementLifecycle Statement 生命周期
     */
    public FederationFragmentExecutionContext(
        QueryId queryId,
        String sql,
        List<SqlParameter> parameters,
        SqlExecutionOptions options,
        DataSource dataSource,
        AdapterCompatibility compatibility,
        Map<String, String> adapterOptions,
        StatementLifecycle statementLifecycle
    ) {
        this(
            queryId,
            sql,
            parameters,
            options,
            dataSource,
            compatibility,
            adapterOptions,
            statementLifecycle,
            FederationExecutionObserver.none(),
            FederationExecutionGuard.none()
        );
    }

    /**
     * 创建带阶段观察器的旧调用兼容上下文。
     *
     * @param queryId 查询标识
     * @param sql 参数化 SQL
     * @param parameters JDBC 参数
     * @param options 执行限制
     * @param dataSource 数据源
     * @param compatibility 数据库兼容信息
     * @param adapterOptions Adapter 选项
     * @param statementLifecycle Statement 生命周期
     * @param observer Fragment 观察器
     */
    public FederationFragmentExecutionContext(
        QueryId queryId,
        String sql,
        List<SqlParameter> parameters,
        SqlExecutionOptions options,
        DataSource dataSource,
        AdapterCompatibility compatibility,
        Map<String, String> adapterOptions,
        StatementLifecycle statementLifecycle,
        FederationExecutionObserver observer
    ) {
        this(
            queryId,
            sql,
            parameters,
            options,
            dataSource,
            compatibility,
            adapterOptions,
            statementLifecycle,
            observer,
            FederationExecutionGuard.none()
        );
    }
}
