package tech.easyflow.log;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * 操作日志记录与保留策略配置。
 */
@Configuration
@ConfigurationProperties(prefix = "easyflow.log-record")
public class LogRecordProperties {

    /**
     * 仅记录此前缀下的请求；为空时不限制请求路径。
     */
    private String recordActionPrefix;

    /**
     * 是否记录未显式标注的只读请求。
     */
    private boolean recordReadActions;

    /**
     * 数据库操作日志保留策略。
     */
    private final Retention retention = new Retention();

    /**
     * 获取请求路径前缀。
     *
     * @return 请求路径前缀
     */
    public String getRecordActionPrefix() {
        return recordActionPrefix;
    }

    /**
     * 设置请求路径前缀。
     *
     * @param recordActionPrefix 请求路径前缀
     */
    public void setRecordActionPrefix(String recordActionPrefix) {
        this.recordActionPrefix = recordActionPrefix;
    }

    /**
     * 判断是否记录未显式标注的只读请求。
     *
     * @return 是否记录只读请求
     */
    public boolean isRecordReadActions() {
        return recordReadActions;
    }

    /**
     * 设置是否记录未显式标注的只读请求。
     *
     * @param recordReadActions 是否记录只读请求
     */
    public void setRecordReadActions(boolean recordReadActions) {
        this.recordReadActions = recordReadActions;
    }

    /**
     * 获取数据库操作日志保留策略。
     *
     * @return 保留策略
     */
    public Retention getRetention() {
        return retention;
    }

    /**
     * 数据库操作日志保留策略。
     */
    public static class Retention {

        private static final int MAX_BATCH_SIZE = 10_000;

        /**
         * 是否启用自动清理。
         */
        private boolean enabled = true;

        /**
         * 在线日志保留天数。
         */
        private int days = 90;

        /**
         * 单批清理行数。
         */
        private int batchSize = 5_000;

        /**
         * 单次调度最多清理批次。
         */
        private int maxBatches = 20;

        /**
         * 判断是否启用自动清理。
         *
         * @return 是否启用
         */
        public boolean isEnabled() {
            return enabled;
        }

        /**
         * 设置是否启用自动清理。
         *
         * @param enabled 是否启用
         */
        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }

        /**
         * 获取在线日志保留天数。
         *
         * @return 保留天数
         */
        public int getDays() {
            return days;
        }

        /**
         * 设置在线日志保留天数。
         *
         * @param days 保留天数，必须大于零
         * @throws IllegalArgumentException 保留天数不合法时抛出
         */
        public void setDays(int days) {
            if (days < 1) {
                throw new IllegalArgumentException("日志保留天数必须大于零");
            }
            this.days = days;
        }

        /**
         * 获取单批清理行数。
         *
         * @return 单批清理行数
         */
        public int getBatchSize() {
            return batchSize;
        }

        /**
         * 设置单批清理行数。
         *
         * @param batchSize 单批清理行数
         * @throws IllegalArgumentException 批次大小不在允许范围内时抛出
         */
        public void setBatchSize(int batchSize) {
            if (batchSize < 1 || batchSize > MAX_BATCH_SIZE) {
                throw new IllegalArgumentException("日志清理批次大小必须在 1 到 10000 之间");
            }
            this.batchSize = batchSize;
        }

        /**
         * 获取单次调度最多清理批次。
         *
         * @return 最大批次数
         */
        public int getMaxBatches() {
            return maxBatches;
        }

        /**
         * 设置单次调度最多清理批次。
         *
         * @param maxBatches 最大批次数，必须大于零
         * @throws IllegalArgumentException 最大批次数不合法时抛出
         */
        public void setMaxBatches(int maxBatches) {
            if (maxBatches < 1) {
                throw new IllegalArgumentException("日志清理最大批次数必须大于零");
            }
            this.maxBatches = maxBatches;
        }
    }
}
