package com.usky.rule.util;

import com.usky.rule.exception.BizException;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Date;
import java.util.stream.Collectors;
import org.quartz.CronExpression;

public class CronUtil {
    public CronUtil() {
    }

    /**
     * 将前端 / 配置中的 cron 规范为 Quartz {@link CronExpression} 可解析形式：
     * <ul>
     *   <li>5 段（分 时 日 月 周）→ 前补秒字段 {@code 0}</li>
     *   <li>7 段且末段为全年通配（{@code *} 或 {@code ?}）→ 去掉年字段，按 6 段解析</li>
     * </ul>
     */
    public static String normalizeCronExpression(String cron) {
        if (cron == null || cron.trim().isEmpty()) {
            return "0 0 * * * ?";
        }
        String s = cron.trim();
        String[] parts = s.split("\\s+");
        if (parts.length == 5) {
            return "0 " + s;
        }
        if (parts.length == 7) {
            String last = parts[6];
            if ("*".equals(last) || "?".equals(last)) {
                return Arrays.stream(parts, 0, 6).collect(Collectors.joining(" "));
            }
        }
        return s;
    }

    /**
     * 判断给定时刻是否落在 cron 调度点上（用于规则「时间范围 / 时间表达式」约束）。
     * 与 {@link #isCronMatched(String)} 不同：后者仅根据是否存在「下一次触发时间」判断，无法表达「当前是否满足」。
     */
    public static boolean isCronSatisfiedBy(String cronExpression, Date at) {
        if (cronExpression == null || cronExpression.trim().isEmpty() || at == null) {
            return false;
        }
        CronExpression cron;
        try {
            cron = new CronExpression(normalizeCronExpression(cronExpression.trim()));
        } catch (ParseException e) {
            throw new BizException(cronExpression + "不是一个正确的cron表达式");
        }
        return cron.isSatisfiedBy(at);
    }

    public static boolean isCronExpired(String cronExpression) {
        CronExpression cron;
        try {
            cron = new CronExpression(cronExpression);
        } catch (ParseException var4) {
            throw new BizException(cronExpression + "不是一个正确的cron表达式");
        }

        Date now = new Date();
        Date next = cron.getNextValidTimeAfter(now);
        return next == null || next.before(now);
    }

    public static boolean isCronMatched(String cronExpression) {
        CronExpression cron;
        try {
            cron = new CronExpression(cronExpression);
        } catch (ParseException var4) {
            throw new BizException(cronExpression + "不是一个正确的cron表达式");
        }

        Date now = new Date();
        Date next = cron.getNextValidTimeAfter(now);
        return next != null;
    }
}
