package com.easyagents.scheduler;

import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 与具体调度实现无关的任务管理服务。
 */
public interface ScheduleService {

    /**
     * 创建任务；同标识同定义重复创建视为幂等成功。
     *
     * @param definition 任务定义
     * @return 创建后的任务视图
     * @throws ScheduleException 同标识存在不同定义或 Provider 失败时抛出
     */
    ScheduleView create(ScheduleDefinition definition);

    /**
     * 将任务完整替换为目标定义，目标不存在时按目标定义创建。
     *
     * @param definition 目标任务定义
     * @return 替换后的任务视图
     * @throws ScheduleException Provider 失败时抛出
     */
    ScheduleView replace(ScheduleDefinition definition);

    /**
     * 暂停任务的计划触发。
     *
     * @param scheduleId 任务标识
     * @return 暂停后的任务视图
     * @throws ScheduleException 任务不存在或 Provider 失败时抛出
     */
    ScheduleView pause(ScheduleId scheduleId);

    /**
     * 恢复任务的计划触发。
     *
     * @param scheduleId 任务标识
     * @return 恢复后的任务视图
     * @throws ScheduleException 任务不存在或 Provider 失败时抛出
     */
    ScheduleView resume(ScheduleId scheduleId);

    /**
     * 删除任务及其计划触发器。
     *
     * @param scheduleId 任务标识
     * @return 存在并删除成功时为 true，原本不存在时为 false
     * @throws ScheduleException Provider 失败时抛出
     */
    boolean delete(ScheduleId scheduleId);

    /**
     * 立即触发一次已存在任务。
     *
     * @param scheduleId 任务标识
     * @param invocationId 调用方生成的链路和幂等标识
     * @param parameters 仅对本次触发生效并覆盖同名基础参数的字符串参数
     * @return 请求接受回执
     * @throws ScheduleException 参数非法、任务不存在或 Provider 失败时抛出
     */
    ScheduleFireReceipt triggerNow(
        ScheduleId scheduleId,
        String invocationId,
        Map<String, String> parameters
    );

    /**
     * 查询任务当前定义和状态。
     *
     * @param scheduleId 任务标识
     * @return 任务不存在时为空
     * @throws ScheduleException Provider 失败时抛出
     */
    Optional<ScheduleView> get(ScheduleId scheduleId);

    /**
     * 从当前时间开始预览后续触发时间，不创建持久任务。
     *
     * @param plan 调度计划
     * @param limit 最大返回数量
     * @return 按时间升序排列的触发时间
     * @throws ScheduleException 计划不合法时抛出
     */
    List<Instant> nextFireTimes(SchedulePlan plan, int limit);
}
