import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Configuration
@EnableScheduling
public class DynamicSchedulingConfig implements SchedulingConfigurer {
    @Autowired
    private ScheduledTaskConfigRepository taskConfigRepository;
    private final Map<Long, Runnable> scheduledTasks = new ConcurrentHashMap<>();
    private final ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskScheduler.initialize();
        // 定时刷新任务配置
        taskRegistrar.addFixedDelayTask(this::refreshTasks, 5000);
        // 添加默认的定时任务(示例)
        taskRegistrar.addTriggerTask(
            () -> System.out.println("默认的定时任务执行了!"),
            triggerContext -> new CronTrigger("0/10 * * * * ?").nextExecutionTime(triggerContext)
        );
    }
    private void refreshTasks() {
        System.out.println("刷新任务配置...");
        // 获取最新的任务配置
        Iterable<ScheduledTaskConfig> taskConfigs = taskConfigRepository.findAll();
        // 根据数据库中的配置更新任务
        updateScheduledTasks(taskConfigs);
    }
    private void updateScheduledTasks(Iterable<ScheduledTaskConfig> taskConfigs) {
        // 遍历数据库中的配置
        for (ScheduledTaskConfig taskConfig : taskConfigs) {
            Long taskId = taskConfig.getId();
            // 如果任务已经注册,但是 Cron 表达式发生了变化,取消旧任务并重新注册
            if (scheduledTasks.containsKey(taskId) && !scheduledTasks.get(taskId).equals(taskConfig.getCronExpression())) {
                cancelTask(taskId);
            }
            // 如果任务未注册,注册新任务
            if (!scheduledTasks.containsKey(taskId)) {
                registerTask(taskConfig);
            }
        }
        // 如果数据库中的任务被删除,取消已注册的任务
        for (Long taskId : scheduledTasks.keySet()) {
            if (StreamSupport.stream(taskConfigs.spliterator(), false)
                .noneMatch(config -> config.getId().equals(taskId))) {
                cancelTask(taskId);
            }
        }
    }
    private void registerTask(ScheduledTaskConfig taskConfig) {
        Long taskId = taskConfig.getId();
        Runnable task = () -> executeTaskLogic(taskConfig);
        scheduledTasks.put(taskId, task);
        // 使用 ThreadPoolTaskScheduler 执行定时任务
        taskScheduler.schedule(task, new CronTrigger(taskConfig.getCronExpression()));
    }
    private void cancelTask(Long taskId) {
        Runnable task = scheduledTasks.remove(taskId);
        taskScheduler.getScheduledThreadPoolExecutor().remove(task);
    }
    private void executeTaskLogic(ScheduledTaskConfig taskConfig) {
        System.out.println("定时任务[" + taskConfig.getTaskName() + "]执行了!");
    }
}