package tech.easyflow.ai.easyagentsflow.config;

import com.easyagents.flow.core.util.IoBulkhead;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.time.Duration;

/**
 * 工作流阻塞 I/O 隔离配置。
 *
 * <p>全部参数均提供宽松默认值，应用无需新增配置即可保持现有业务行为。</p>
 */
@ConfigurationProperties(prefix = "easyflow.workflow.io")
public class WorkflowIoProperties {

    private Lane http = new Lane(64, 16, Duration.ofSeconds(1), 1_024);
    private Lane dataset = new Lane(32, 8, Duration.ofSeconds(1), 512);
    private Lane storage = new Lane(24, 12, Duration.ofSeconds(2), 256);
    private Lane documentParse = new Lane(8, 4, Duration.ofSeconds(2), 128);
    private Lane responseAggregation =
            new Lane(8, 4, Duration.ofSeconds(2), 1_024);

    /**
     * 获取 HTTP 隔离配置。
     *
     * @return HTTP 配置
     */
    public Lane getHttp() {
        return http;
    }

    /**
     * 设置 HTTP 隔离配置。
     *
     * @param http HTTP 配置
     */
    public void setHttp(Lane http) {
        this.http = http;
    }

    /**
     * 获取数据集隔离配置。
     *
     * @return 数据集配置
     */
    public Lane getDataset() {
        return dataset;
    }

    /**
     * 设置数据集隔离配置。
     *
     * @param dataset 数据集配置
     */
    public void setDataset(Lane dataset) {
        this.dataset = dataset;
    }

    /**
     * 获取对象存储隔离配置。
     *
     * @return 对象存储配置
     */
    public Lane getStorage() {
        return storage;
    }

    /**
     * 设置对象存储隔离配置。
     *
     * @param storage 对象存储配置
     */
    public void setStorage(Lane storage) {
        this.storage = storage;
    }

    /**
     * 获取文档解析隔离配置。
     *
     * @return 文档解析配置
     */
    public Lane getDocumentParse() {
        return documentParse;
    }

    /**
     * 设置文档解析隔离配置。
     *
     * @param documentParse 文档解析配置
     */
    public void setDocumentParse(Lane documentParse) {
        this.documentParse = documentParse;
    }

    /**
     * 获取响应聚合隔离配置。
     *
     * @return 响应聚合配置
     */
    public Lane getResponseAggregation() {
        return responseAggregation;
    }

    /**
     * 设置响应聚合隔离配置。
     *
     * @param responseAggregation 响应聚合配置
     */
    public void setResponseAggregation(Lane responseAggregation) {
        this.responseAggregation = responseAggregation;
    }

    /**
     * 单类阻塞 I/O 的容量配置。
     */
    public static class Lane {

        private int maxConcurrency;
        private int perTargetMaxConcurrency;
        private Duration acquireTimeout;
        private int maxTrackedTargets;

        /**
         * 创建供 Spring 绑定使用的空配置对象。
         */
        public Lane() {
        }

        /**
         * 创建带默认值的隔离配置。
         *
         * @param maxConcurrency 总并发
         * @param perTargetMaxConcurrency 单目标并发
         * @param acquireTimeout 许可等待时间
         * @param maxTrackedTargets 最大目标数
         */
        public Lane(
                int maxConcurrency,
                int perTargetMaxConcurrency,
                Duration acquireTimeout,
                int maxTrackedTargets) {
            this.maxConcurrency = maxConcurrency;
            this.perTargetMaxConcurrency = perTargetMaxConcurrency;
            this.acquireTimeout = acquireTimeout;
            this.maxTrackedTargets = maxTrackedTargets;
        }

        /**
         * 转换为引擎配置并完成启动期校验。
         *
         * @return 引擎隔离配置
         * @throws IllegalArgumentException 配置值无效时抛出
         */
        public IoBulkhead.Settings toSettings() {
            return new IoBulkhead.Settings(
                    maxConcurrency,
                    perTargetMaxConcurrency,
                    acquireTimeout,
                    maxTrackedTargets);
        }

        /**
         * 获取总并发。
         *
         * @return 总并发
         */
        public int getMaxConcurrency() {
            return maxConcurrency;
        }

        /**
         * 设置总并发。
         *
         * @param maxConcurrency 总并发
         */
        public void setMaxConcurrency(int maxConcurrency) {
            this.maxConcurrency = maxConcurrency;
        }

        /**
         * 获取单目标并发。
         *
         * @return 单目标并发
         */
        public int getPerTargetMaxConcurrency() {
            return perTargetMaxConcurrency;
        }

        /**
         * 设置单目标并发。
         *
         * @param perTargetMaxConcurrency 单目标并发
         */
        public void setPerTargetMaxConcurrency(
                int perTargetMaxConcurrency) {
            this.perTargetMaxConcurrency =
                    perTargetMaxConcurrency;
        }

        /**
         * 获取许可等待时间。
         *
         * @return 等待时间
         */
        public Duration getAcquireTimeout() {
            return acquireTimeout;
        }

        /**
         * 设置许可等待时间。
         *
         * @param acquireTimeout 等待时间
         */
        public void setAcquireTimeout(Duration acquireTimeout) {
            this.acquireTimeout = acquireTimeout;
        }

        /**
         * 获取最大目标数。
         *
         * @return 最大目标数
         */
        public int getMaxTrackedTargets() {
            return maxTrackedTargets;
        }

        /**
         * 设置最大目标数。
         *
         * @param maxTrackedTargets 最大目标数
         */
        public void setMaxTrackedTargets(int maxTrackedTargets) {
            this.maxTrackedTargets = maxTrackedTargets;
        }
    }
}
