package com.easyagents.scheduler.spring.boot;

import com.easyagents.scheduler.quartz.QuartzSchedulerConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * Easy Agents 嵌入式调度器配置。
 */
@ConfigurationProperties(prefix = "easy-agents.scheduler")
public class EasyAgentsSchedulerProperties {

    /** 是否显式启用调度器。 */
    private boolean enabled;

    /** 多 DataSource 场景下选用的 Bean 名称。 */
    private String dataSourceBeanName;

    /** Quartz Provider 配置。 */
    private Quartz quartz = new Quartz();

    /**
     * 创建默认调度器配置。
     */
    public EasyAgentsSchedulerProperties() {
    }

    /**
     * 返回是否启用调度器。
     *
     * @return 启用状态
     */
    public boolean isEnabled() {
        return enabled;
    }

    /**
     * 设置是否启用调度器。
     *
     * @param enabled 启用状态
     */
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    /**
     * 返回指定 DataSource Bean 名称。
     *
     * @return Bean 名称，可为空
     */
    public String getDataSourceBeanName() {
        return dataSourceBeanName;
    }

    /**
     * 设置指定 DataSource Bean 名称。
     *
     * @param dataSourceBeanName Bean 名称
     */
    public void setDataSourceBeanName(String dataSourceBeanName) {
        this.dataSourceBeanName = dataSourceBeanName;
    }

    /**
     * 返回 Quartz Provider 配置。
     *
     * @return Quartz 配置
     */
    public Quartz getQuartz() {
        return quartz;
    }

    /**
     * 设置 Quartz Provider 配置。
     *
     * @param quartz Quartz 配置
     */
    public void setQuartz(Quartz quartz) {
        this.quartz = quartz;
    }

    /**
     * Quartz Provider 属性集合。
     */
    public static class Quartz {

        /** Scheduler Name，同一集群保持一致。 */
        private String schedulerName = "easyAgentsScheduler";

        /** 当前实例标识。 */
        private String instanceId = "AUTO";

        /** Quartz 表前缀，可包含 Schema。 */
        private String tablePrefix = "QRTZ_";

        /** Quartz JDBC DriverDelegate 类名。 */
        private String driverDelegateClass = QuartzSchedulerConfig.STANDARD_JDBC_DELEGATE;

        /** 是否启用 JDBC 集群。 */
        private boolean clustered = true;

        /** Quartz Worker 线程数。 */
        private int threadCount = 8;

        /** Quartz Worker 线程优先级。 */
        private int threadPriority = Thread.NORM_PRIORITY;

        /** 单次批量获取 Trigger 的最大数量。 */
        private int batchTriggerAcquisitionMaxCount = 1;

        /** 可提前纳入批量的时间窗口，单位毫秒。 */
        private long batchTriggerAcquisitionFireAheadTimeWindowMillis;

        /** 集群心跳间隔，单位毫秒。 */
        private long clusterCheckinIntervalMillis = 15_000L;

        /** Misfire 判定阈值，单位毫秒。 */
        private long misfireThresholdMillis = 60_000L;

        /** 关闭时是否等待运行中任务完成。 */
        private boolean waitForJobsToCompleteOnShutdown = true;

        /** 关闭等待运行中任务的最长时间，单位毫秒。 */
        private long shutdownWaitTimeoutMillis = 30_000L;

        /** 启动前是否只读校验 Quartz 表结构。 */
        private boolean validateSchema = true;

        /**
         * 创建默认 Quartz Provider 配置。
         */
        public Quartz() {
        }

        /**
         * 返回 Scheduler Name。
         *
         * @return Scheduler Name
         */
        public String getSchedulerName() {
            return schedulerName;
        }

        /**
         * 设置 Scheduler Name。
         *
         * @param schedulerName Scheduler Name
         */
        public void setSchedulerName(String schedulerName) {
            this.schedulerName = schedulerName;
        }

        /**
         * 返回实例标识。
         *
         * @return 实例标识
         */
        public String getInstanceId() {
            return instanceId;
        }

        /**
         * 设置实例标识。
         *
         * @param instanceId 实例标识
         */
        public void setInstanceId(String instanceId) {
            this.instanceId = instanceId;
        }

        /**
         * 返回表前缀。
         *
         * @return 表前缀
         */
        public String getTablePrefix() {
            return tablePrefix;
        }

        /**
         * 设置表前缀。
         *
         * @param tablePrefix 表前缀
         */
        public void setTablePrefix(String tablePrefix) {
            this.tablePrefix = tablePrefix;
        }

        /**
         * 返回 JDBC Delegate 类名。
         *
         * @return Delegate 类名
         */
        public String getDriverDelegateClass() {
            return driverDelegateClass;
        }

        /**
         * 设置 JDBC Delegate 类名。
         *
         * @param driverDelegateClass Delegate 类名
         */
        public void setDriverDelegateClass(String driverDelegateClass) {
            this.driverDelegateClass = driverDelegateClass;
        }

        /**
         * 返回是否启用集群。
         *
         * @return 集群状态
         */
        public boolean isClustered() {
            return clustered;
        }

        /**
         * 设置是否启用集群。
         *
         * @param clustered 集群状态
         */
        public void setClustered(boolean clustered) {
            this.clustered = clustered;
        }

        /**
         * 返回 Worker 线程数。
         *
         * @return 线程数
         */
        public int getThreadCount() {
            return threadCount;
        }

        /**
         * 设置 Worker 线程数。
         *
         * @param threadCount 线程数
         */
        public void setThreadCount(int threadCount) {
            this.threadCount = threadCount;
        }

        /**
         * 返回 Worker 线程优先级。
         *
         * @return 线程优先级
         */
        public int getThreadPriority() {
            return threadPriority;
        }

        /**
         * 设置 Worker 线程优先级。
         *
         * @param threadPriority 线程优先级
         */
        public void setThreadPriority(int threadPriority) {
            this.threadPriority = threadPriority;
        }

        /**
         * 返回单次批量获取 Trigger 的最大数量。
         *
         * @return 批量上限
         */
        public int getBatchTriggerAcquisitionMaxCount() {
            return batchTriggerAcquisitionMaxCount;
        }

        /**
         * 设置单次批量获取 Trigger 的最大数量。
         *
         * @param batchTriggerAcquisitionMaxCount 批量上限
         */
        public void setBatchTriggerAcquisitionMaxCount(
                int batchTriggerAcquisitionMaxCount) {
            this.batchTriggerAcquisitionMaxCount = batchTriggerAcquisitionMaxCount;
        }

        /**
         * 返回可提前纳入批量的时间窗口。
         *
         * @return 毫秒窗口
         */
        public long getBatchTriggerAcquisitionFireAheadTimeWindowMillis() {
            return batchTriggerAcquisitionFireAheadTimeWindowMillis;
        }

        /**
         * 设置可提前纳入批量的时间窗口。
         *
         * @param batchTriggerAcquisitionFireAheadTimeWindowMillis 毫秒窗口
         */
        public void setBatchTriggerAcquisitionFireAheadTimeWindowMillis(
                long batchTriggerAcquisitionFireAheadTimeWindowMillis) {
            this.batchTriggerAcquisitionFireAheadTimeWindowMillis =
                batchTriggerAcquisitionFireAheadTimeWindowMillis;
        }

        /**
         * 返回集群心跳间隔。
         *
         * @return 毫秒间隔
         */
        public long getClusterCheckinIntervalMillis() {
            return clusterCheckinIntervalMillis;
        }

        /**
         * 设置集群心跳间隔。
         *
         * @param clusterCheckinIntervalMillis 毫秒间隔
         */
        public void setClusterCheckinIntervalMillis(long clusterCheckinIntervalMillis) {
            this.clusterCheckinIntervalMillis = clusterCheckinIntervalMillis;
        }

        /**
         * 返回 Misfire 判定阈值。
         *
         * @return 毫秒阈值
         */
        public long getMisfireThresholdMillis() {
            return misfireThresholdMillis;
        }

        /**
         * 设置 Misfire 判定阈值。
         *
         * @param misfireThresholdMillis 毫秒阈值
         */
        public void setMisfireThresholdMillis(long misfireThresholdMillis) {
            this.misfireThresholdMillis = misfireThresholdMillis;
        }

        /**
         * 返回关闭时是否等待在途任务。
         *
         * @return 等待状态
         */
        public boolean isWaitForJobsToCompleteOnShutdown() {
            return waitForJobsToCompleteOnShutdown;
        }

        /**
         * 设置关闭时是否等待在途任务。
         *
         * @param waitForJobsToCompleteOnShutdown 等待状态
         */
        public void setWaitForJobsToCompleteOnShutdown(
            boolean waitForJobsToCompleteOnShutdown
        ) {
            this.waitForJobsToCompleteOnShutdown = waitForJobsToCompleteOnShutdown;
        }

        /**
         * 返回关闭等待的最长时间。
         *
         * @return 毫秒数
         */
        public long getShutdownWaitTimeoutMillis() {
            return shutdownWaitTimeoutMillis;
        }

        /**
         * 设置关闭等待的最长时间。
         *
         * @param shutdownWaitTimeoutMillis 毫秒数
         */
        public void setShutdownWaitTimeoutMillis(long shutdownWaitTimeoutMillis) {
            this.shutdownWaitTimeoutMillis = shutdownWaitTimeoutMillis;
        }

        /**
         * 返回是否校验数据库结构。
         *
         * @return 校验状态
         */
        public boolean isValidateSchema() {
            return validateSchema;
        }

        /**
         * 设置是否校验数据库结构。
         *
         * @param validateSchema 校验状态
         */
        public void setValidateSchema(boolean validateSchema) {
            this.validateSchema = validateSchema;
        }
    }
}
