package com.usky.rule.schedule;

import com.usky.rule.mapper.RuleEngineCronMapper;
import com.usky.rule.service.RuleEngineService;
import com.usky.rule.vo.RuleEngineCronVO;
import lombok.extern.slf4j.Slf4j;
import org.quartz.CronExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

/**
 * 数据规则引擎定时任务调度器（参考能耗 leo-rule-engine）。
 * 按分钟扫描已启用规则的 cron 配置（getTurnedOnCron），若当前时间满足 cron 则触发规则并写 rule_engine_log（trigger_type=cron）。
 */
@Slf4j
@Component
@ConditionalOnProperty(name = "rule-engine.cron-schedule.enabled", havingValue = "true", matchIfMissing = true)
public class RuleEngineCronScheduler {

    private final RuleEngineCronMapper ruleEngineCronMapper;
    private final RuleEngineService ruleEngineService;

    public RuleEngineCronScheduler(RuleEngineCronMapper ruleEngineCronMapper,
                                   RuleEngineService ruleEngineService) {
        this.ruleEngineCronMapper = ruleEngineCronMapper;
        this.ruleEngineService = ruleEngineService;
    }

    /**
     * 每分钟整秒执行一次，拉取所有已启用规则及其 cron，匹配当前时间则触发（对应 leo Quartz + getTurnedOnCron）
     */
    @Scheduled(cron = "0 * * * * ?")
    public void runCronRules() {
        List<RuleEngineCronVO> list;
        try {
            list = ruleEngineCronMapper.getTurnedOnCron();
        } catch (Exception e) {
            log.warn("getTurnedOnCron error", e);
            return;
        }
        if (list == null || list.isEmpty()) {
            return;
        }
        Date now = new Date();
        for (RuleEngineCronVO vo : list) {
            if (vo.getRuleEngineId() == null || vo.getCron() == null || vo.getCron().trim().isEmpty()) {
                continue;
            }
            try {
                String cronStr = normalizeCron(vo.getCron().trim());
                CronExpression expression = new CronExpression(cronStr);
                if (expression.isSatisfiedBy(now)) {
                    ruleEngineService.triggerByCron(vo.getRuleEngineId());
                    log.debug("rule cron triggered ruleEngineId={} cron={}", vo.getRuleEngineId(), vo.getCron());
                }
            } catch (Exception e) {
                log.warn("cron parse or trigger error ruleEngineId={} cron={}", vo.getRuleEngineId(), vo.getCron(), e);
            }
        }
    }

    /** Quartz 为 6 段（秒 分 时 日 月 周）；若为 5 段（分 时 日 月 周）则前补秒 0 */
    private static String normalizeCron(String cron) {
        if (cron == null) {
            return "0 0 * * * ?";
        }
        String s = cron.trim();
        int n = s.split("\\s+").length;
        if (n == 5) {
            return "0 " + s;
        }
        return s;
    }
}
