package com.gyee.edge.protocol.iec60870;

import java.util.concurrent.PriorityBlockingQueue;

class TimeoutManager implements Runnable {

    private final PriorityBlockingQueue<TimeoutTask> queue;

    private final Object guadedLock;

    boolean canceled;

    public TimeoutManager() {
        this.queue = new PriorityBlockingQueue<>(4);
        this.guadedLock = new Object();
    }

    public void addTimerTask(TimeoutTask task) {
        task.updateDueTime();
        removeDuplicates(task);
        this.queue.add(task);
        synchronized (this.guadedLock) {
            this.guadedLock.notifyAll();
        }
    }

    private void removeDuplicates(TimeoutTask task) {
        while (queue.remove(task)) {
            ;
        }
    }

    public void cancel() {
        this.canceled = true;
    }

    @Override
    public void run() {
        Thread.currentThread().setName("TimeoutManager");
        TimeoutTask currTask;
        while (!canceled) {
            try {
                long sleepMillis;
                currTask = queue.take();

                while ((sleepMillis = currTask.sleepTimeFromDueTime()) > 0) {
                    queue.put(currTask);

                    synchronized (this.guadedLock) {
                        this.guadedLock.wait(sleepMillis);
                    }
                    currTask = queue.take();
                }

                currTask.manExec();
            } catch (InterruptedException e) {
                // Restore interrupted state...
                Thread.currentThread().interrupt();
                return;
            }
        }
    }
}
