package tech.easyflow.common.mq.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.StringUtils;

import java.time.Duration;

/**
 * EasyFlow MQ 配置。
 */
@ConfigurationProperties(prefix = "easyflow.mq")
public class MQProperties {

    private boolean enabled = true;
    private String type = "redis";
    private final Redis redis = new Redis();

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Redis getRedis() {
        return redis;
    }

    public static class Redis {

        private int database = 1;
        private String streamPrefix = "easyflow:mq";
        private String consumerInstanceId = defaultConsumerInstanceId();
        private int chatPersistShardCount = 4;
        private int consumerBatchSize = 200;
        private Duration consumerBlockTimeout = Duration.ofMillis(2000);
        private Duration pendingClaimIdle = Duration.ofMillis(60000);
        private int maxRetry = 16;
        private ConsumerExecutor consumerExecutor = new ConsumerExecutor();
        private Pool pool = new Pool();

        public int getDatabase() {
            return database;
        }

        public void setDatabase(int database) {
            this.database = database;
        }

        public String getStreamPrefix() {
            return streamPrefix;
        }

        public void setStreamPrefix(String streamPrefix) {
            this.streamPrefix = streamPrefix;
        }

        /**
         * 获取 Redis Stream 消费实例 ID。
         *
         * @return 消费实例 ID
         */
        public String getConsumerInstanceId() {
            return consumerInstanceId;
        }

        /**
         * 设置 Redis Stream 消费实例 ID。
         *
         * @param consumerInstanceId 消费实例 ID
         */
        public void setConsumerInstanceId(String consumerInstanceId) {
            this.consumerInstanceId = StringUtils.hasText(consumerInstanceId)
                ? consumerInstanceId.trim()
                : defaultConsumerInstanceId();
        }

        public int getChatPersistShardCount() {
            return chatPersistShardCount;
        }

        public void setChatPersistShardCount(int chatPersistShardCount) {
            this.chatPersistShardCount = chatPersistShardCount;
        }

        public int getConsumerBatchSize() {
            return consumerBatchSize;
        }

        public void setConsumerBatchSize(int consumerBatchSize) {
            this.consumerBatchSize = consumerBatchSize;
        }

        public Duration getConsumerBlockTimeout() {
            return consumerBlockTimeout;
        }

        public void setConsumerBlockTimeout(Duration consumerBlockTimeout) {
            this.consumerBlockTimeout = consumerBlockTimeout;
        }

        public Duration getPendingClaimIdle() {
            return pendingClaimIdle;
        }

        public void setPendingClaimIdle(Duration pendingClaimIdle) {
            this.pendingClaimIdle = pendingClaimIdle;
        }

        public int getMaxRetry() {
            return maxRetry;
        }

        public void setMaxRetry(int maxRetry) {
            this.maxRetry = maxRetry;
        }

        public ConsumerExecutor getConsumerExecutor() {
            return consumerExecutor;
        }

        public void setConsumerExecutor(ConsumerExecutor consumerExecutor) {
            this.consumerExecutor = consumerExecutor;
        }

        public Pool getPool() {
            return pool;
        }

        public void setPool(Pool pool) {
            this.pool = pool;
        }

        /**
         * Redis MQ 消费线程池配置。
         */
        public static class ConsumerExecutor {

            private int coreSize = 4;
            private int maxSize = 12;
            private int queueCapacity = 64;
            private int keepAliveSeconds = 60;

            public int getCoreSize() {
                return coreSize;
            }

            public void setCoreSize(int coreSize) {
                this.coreSize = coreSize;
            }

            public int getMaxSize() {
                return maxSize;
            }

            public void setMaxSize(int maxSize) {
                this.maxSize = maxSize;
            }

            public int getQueueCapacity() {
                return queueCapacity;
            }

            public void setQueueCapacity(int queueCapacity) {
                this.queueCapacity = queueCapacity;
            }

            public int getKeepAliveSeconds() {
                return keepAliveSeconds;
            }

            public void setKeepAliveSeconds(int keepAliveSeconds) {
                this.keepAliveSeconds = keepAliveSeconds;
            }
        }

        /**
         * Redis MQ 连接池配置。
         */
        public static class Pool {

            private int maxActive = 12;
            private int maxIdle = 8;
            private int minIdle = 1;

            public int getMaxActive() {
                return maxActive;
            }

            public void setMaxActive(int maxActive) {
                this.maxActive = maxActive;
            }

            public int getMaxIdle() {
                return maxIdle;
            }

            public void setMaxIdle(int maxIdle) {
                this.maxIdle = maxIdle;
            }

            public int getMinIdle() {
                return minIdle;
            }

            public void setMinIdle(int minIdle) {
                this.minIdle = minIdle;
            }
        }

        private static String defaultConsumerInstanceId() {
            String hostName = System.getenv("HOSTNAME");
            if (StringUtils.hasText(hostName)) {
                return hostName.trim();
            }
            return java.util.UUID.randomUUID().toString();
        }
    }
}
