package com.cyksj.task;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskRejectedException;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.TaskUtils;
import org.springframework.stereotype.Component;

import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/**
 * @author valor.
 * @date 2019-07-25 16:30
 */
@Component
public class JobManager {

    @Autowired
    private ThreadPoolTaskScheduler taskScheduler;

    /**
     * 定时任务管理
     * todo oom
     */
//    private static volatile Map<String, ScheduledFuture<?>> jobs;

    private static volatile JobManager jobManager;

    private JobManager() { }

    public static JobManager getInstance() {
        if (null == jobManager) {
            synchronized (JobManager.class) {
                if (null == jobManager) {
                    jobManager = new JobManager();
                }
            }
        }
        return jobManager;
    }

//    private Map<String, ScheduledFuture<?>> getJobs() {
//        if (null == jobs) {
//            synchronized (JobManager.class) {
//                if (null == jobs) {
//                    jobs = new ConcurrentHashMap<>(16);
//                }
//            }
//        }
//        return jobs;
//    }

    /**
     * 任务监视器
     */
//    public List<String> monitor() {
//        Set<Map.Entry<String, ScheduledFuture<?>>> entrySet = this.getJobs().entrySet();
//
//        List<String> list = new ArrayList<>(entrySet.size());
//
//        entrySet.removeIf(entry -> {
//            ScheduledFuture<?> value = entry.getValue();
//            if (null == value || value.isCancelled() || value.isDone()) {
//                return true;
//            }
//            list.add(entry.getKey());
//            return false;
//        });
//
//        return list;
//    }

    /**
     * 判断任务是否存在
     */
//    public boolean hasJob(String jobName) {
//        return this.getJobs().containsKey(jobName) && null != this.getJobs().get(jobName);
//    }

    /**
     * 取消任务
     */
//    public void cancel(String jobName) {
//        boolean f = this.hasJob(jobName);
//        if (f) {
//            this.getJobs().get(jobName).cancel(false);
//            this.getJobs().remove(jobName);
//        }
//    }

    /**
     * 添加任务
     */
    public void addJob(long startTime, Runnable task) {
        ScheduledExecutorService executor = this.taskScheduler.getScheduledExecutor();
        try {
            Runnable runnable = TaskUtils.decorateTaskWithErrorHandler(task, TaskUtils.LOG_AND_PROPAGATE_ERROR_HANDLER, false);
            ScheduledFuture<?> future = executor.schedule(runnable, startTime, TimeUnit.MILLISECONDS);

//            this.getJobs().put(jobName, future);
        } catch (RejectedExecutionException ex) {
            throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, ex);
        }
    }

}
