package com.easyagents.federation.sql.execute;

import java.util.concurrent.TimeUnit;

/**
 * 贯穿连接获取、Statement 执行和结果读取的查询终态检查器。
 */
public interface FederationExecutionGuard {

    /**
     * 检查查询是否仍允许继续执行。
     *
     * @throws RuntimeException 查询取消或超时时抛出稳定异常
     */
    void ensureAllowed();

    /**
     * 返回查询剩余时限。
     *
     * @return 剩余纳秒数；无限制时返回 {@link Long#MAX_VALUE}
     */
    long remainingNanos();

    /**
     * 将调用方 JDBC 秒级超时收敛到统一剩余时限。
     *
     * @param requestedSeconds 调用方超时，0 表示未指定
     * @return 至少 1 秒的 JDBC 超时；无限制且未指定时返回 0
     */
    default int boundedQueryTimeoutSeconds(int requestedSeconds) {
        if (remainingNanos() == Long.MAX_VALUE) {
            return requestedSeconds;
        }
        long remainingSeconds = Math.max(
            1L,
            TimeUnit.NANOSECONDS.toSeconds(Math.max(1L, remainingNanos()))
        );
        int bounded = (int) Math.min(Integer.MAX_VALUE, remainingSeconds);
        return requestedSeconds == 0 ? bounded : Math.min(requestedSeconds, bounded);
    }

    /**
     * 返回无限制检查器，供旧 Adapter 调用兼容使用。
     *
     * @return 无限制检查器
     */
    static FederationExecutionGuard none() {
        return NoopHolder.INSTANCE;
    }

    /** 无状态实例持有者。 */
    final class NoopHolder {
        private static final FederationExecutionGuard INSTANCE = new FederationExecutionGuard() {
            @Override
            public void ensureAllowed() {
            }

            @Override
            public long remainingNanos() {
                return Long.MAX_VALUE;
            }
        };

        private NoopHolder() {
        }
    }
}
