package com.yh.saas.plugin.news.util.thread;

public final class ObservableRunnable implements Runnable {

    /**
     * 监听者
     */
    protected final LifeCycleListener listener;
    /**
     * 包装的任务类
     */
    private final Runnable task;

    public ObservableRunnable(LifeCycleListener listener, Runnable task) {
        this.listener = listener;
        this.task = task;
    }

    @Override
    public void run() {
        try {
            // 通知任务开始执行
            notifyChange(new RunnableEvent(RunnableState.RUNTIME, Thread.currentThread(), null));
            task.run();
            // 任务执行结束
            notifyChange(new RunnableEvent(RunnableState.DONE, Thread.currentThread(), null));
        } catch (Throwable e) {
            // 任务执行错误
            notifyChange(new RunnableEvent(RunnableState.ERROR, Thread.currentThread(), e));
        }
    }

    protected void notifyChange(final RunnableEvent event) {
        listener.onEvent(event);
    }

    public enum RunnableState {
        /**
         * 任务执行中
         */
        RUNTIME,
        /**
         * 任务执行错误
         */
        ERROR,
        /**
         * 任务执行结束
         */
        DONE
    }

    public static class RunnableEvent {
        private final RunnableState state;
        private final Thread thread;
        private final Throwable cause;

        public RunnableEvent(RunnableState state, Thread thread, Throwable cause) {
            this.state = state;
            this.thread = thread;
            this.cause = cause;
        }

        public RunnableState getState() {
            return state;
        }

        public Thread getThread() {
            return thread;
        }

        public Throwable getCause() {
            return cause;
        }
    }

}
