package com.lanyuanxiaoyao.service.scheduler.strategy;

import cn.hutool.core.util.RandomUtil;
import com.lanyuanxiaoyao.service.common.Constants;
import java.time.Instant;
import java.util.Date;
import org.quartz.*;

import static com.lanyuanxiaoyao.service.common.Constants.SECOND;

/**
 * @author ZhangJiacheng
 * @date 2023-06-06
 */
public abstract class ScheduleStrategyImpl implements ScheduleStrategy {
    protected final String name;
    protected final String comment;

    protected ScheduleStrategyImpl(String name, String comment) {
        this.name = name;
        this.comment = comment;
    }

    public static ScheduleStrategy simple(String name, String comment, Class<? extends Job> job, String cron) {
        return simple(true, name, comment, job, cron);
    }

    public static ScheduleStrategy simple(Boolean show, String name, String comment, Class<? extends Job> job, String cron) {
        return new ScheduleStrategyImpl(name, comment) {
            @Override
            public Boolean show() {
                return show;
            }

            @Override
            public JobDetail job() {
                return generateJob(job);
            }

            @Override
            public Trigger trigger() {
                return generateTrigger(cron);
            }
        };
    }

    @Override
    public Boolean enable() {
        return true;
    }

    @Override
    public String name() {
        return name;
    }

    @Override
    public String comment() {
        return comment;
    }

    @Override
    public String toString() {
        return "BaseScheduleStrategy{" +
               "name='" + name + '\'' +
               ", comment='" + comment + '\'' +
               '}';
    }

    protected JobDetail generateJob(Class<? extends Job> job) {
        return JobBuilder.newJob()
                .withIdentity(name + "_job")
                .withDescription(comment)
                .ofType(job)
                .build();
    }

    protected Trigger generateTrigger(String cron) {
        return TriggerBuilder.newTrigger()
                .withIdentity(name + "trigger")
                .withDescription(cron)
                .withSchedule(
                        CronScheduleBuilder
                                .cronSchedule(cron)
                                .withMisfireHandlingInstructionFireAndProceed())
                .startAt(Date.from(Instant.now().plusMillis(SECOND * RandomUtil.randomInt(30, 60))))
                .build();
    }
}
