package com.easyagents.federation.sql.adapter.jdbc;

import com.easyagents.federation.sql.api.FederationSqlErrorCode;
import com.easyagents.federation.sql.api.FederationSqlException;
import com.easyagents.federation.sql.execute.StatementLifecycle;
import java.sql.SQLTimeoutException;

/**
 * 按查询注册表已经确定的终态分类 JDBC 执行与读取异常。
 */
final class JdbcFailureClassifier {

    /**
     * 工具类无需实例化。
     */
    private JdbcFailureClassifier() {
    }

    /**
     * 将 JDBC 异常转换为稳定的查询错误，优先保留先到达的取消或超时终态。
     *
     * @param lifecycle 查询 Statement 生命周期
     * @param cause JDBC 或驱动异常
     * @param timeoutMessage 超时提示
     * @param cancellationMessage 取消提示
     * @param failureMessage 普通执行失败提示
     * @return 分类后的统一异常
     */
    static FederationSqlException classify(
        StatementLifecycle lifecycle,
        Throwable cause,
        String timeoutMessage,
        String cancellationMessage,
        String failureMessage
    ) {
        FederationSqlErrorCode errorCode;
        String message;
        if (lifecycle.timeoutRequested()) {
            errorCode = FederationSqlErrorCode.QUERY_TIMEOUT;
            message = timeoutMessage;
        } else if (lifecycle.cancellationRequested()) {
            // Statement.cancel() 后部分驱动会抛 SQLTimeoutException，已登记的取消终态必须优先。
            errorCode = FederationSqlErrorCode.QUERY_CANCELLED;
            message = cancellationMessage;
        } else if (cause instanceof SQLTimeoutException) {
            errorCode = FederationSqlErrorCode.QUERY_TIMEOUT;
            message = timeoutMessage;
        } else {
            errorCode = FederationSqlErrorCode.EXECUTION_FAILED;
            message = failureMessage;
        }
        return new FederationSqlException(errorCode, message, cause);
    }
}
