/*
 * Copyright 2015-present Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.onlab.util;

import com.google.common.collect.Lists;
import org.onlab.junit.TestUtils;
import org.slf4j.Logger;

import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.junit.TestTools.delay;
import static org.slf4j.LoggerFactory.getLogger;


/**
 * Provides manually scheduled timer utility. All schedulable methods are subject to overflow (you can set a period of
 * max long).  Additionally if a skip skips a period of time greater than one period for a periodic task that task will
 * only be executed once for that skip and scheduled it's period after the last execution.
 */
public class ManuallyAdvancingTimer extends java.util.Timer {

    /* States whether or not the static values from timer task have been set ensures population will only occur once.*/
    private boolean staticsPopulated = false;

    /* Virgin value from timer task */
    private int virginState;

    /* Scheduled value from timer task */
    private int scheduledState;

    /* Executed value from timer task */
    private int executedState;

    /* Cancelled value from timer task */
    private int cancelledState;

    private final Logger logger = getLogger(getClass());

    /* Service for executing timer tasks */
    private final ExecutorService executorService = Executors.newSingleThreadExecutor();

    /* Internal time representation independent of system time, manually advanced */
    private final TimerKeeper timerKeeper = new TimerKeeper();

    /* Data structure for tracking tasks */
    private final TaskQueue queue = new TaskQueue();

    /* Whether execution should execute on the executor thread or the calling thread. */
    private final boolean runLocally;

    public ManuallyAdvancingTimer(boolean runLocally) {
        this.runLocally = runLocally;
    }


    @Override
    public void schedule(TimerTask task, long delay) {
        if (!staticsPopulated) {
            populateStatics(task);
        }
        if (!submitTask(task, delay > 0 ? timerKeeper.currentTimeInMillis() + delay :
                timerKeeper.currentTimeInMillis() - delay, 0)) {
            logger.error("Failed to submit task");
        }
    }

    @Override
    public void schedule(TimerTask task, Date time) {
        if (!staticsPopulated) {
            populateStatics(task);
        }
        if (!submitTask(task, time.getTime(), 0)) {
            logger.error("Failed to submit task");
        }
    }

    @Override
    public void schedule(TimerTask task, long delay, long period) {
        if (!staticsPopulated) {
            populateStatics(task);
        }
        if (!submitTask(task, delay > 0 ? timerKeeper.currentTimeInMillis() + delay :
                timerKeeper.currentTimeInMillis() - delay, period)) {
            logger.error("Failed to submit task");
        }
    }

    @Override
    public void schedule(TimerTask task, Date firstTime, long period) {
        if (!staticsPopulated) {
            populateStatics(task);
        }
        if (!submitTask(task, firstTime.getTime(), period)) {
            logger.error("Failed to submit task");
        }
    }

    /*################################################WARNING################################################*/
    /* Schedule at fixed rate methods do not work exactly as in the java timer. They are clones of the periodic
    *scheduling methods. */
    @Override
    public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
        if (!staticsPopulated) {
            populateStatics(task);
        }
        if (!submitTask(task, delay > 0 ? timerKeeper.currentTimeInMillis() + delay :
                timerKeeper.currentTimeInMillis() - delay, period)) {
            logger.error("Failed to submit task");
        }
    }

    @Override
    public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) {
        if (!staticsPopulated) {
            populateStatics(task);
        }
        if (!submitTask(task, firstTime.getTime(), period)) {
            logger.error("Failed to submit task");
        }
    }

    @Override
    public void cancel() {
        executorService.shutdown();
        queue.clear();
    }

    @Override
    public int purge() {
        return queue.removeCancelled();
    }

    /**
     * Returns the virtual current time in millis.
     *
     * @return long representing simulated current time.
     */
    public long currentTimeInMillis() {
        return timerKeeper.currentTimeInMillis();
    }

    /**
     * Returns the new simulated current time in millis after advancing the absolute value of millis to advance.
     * Triggers event execution of all events scheduled for execution at times up to and including the returned time.
     * Passing in the number zero has no effect.
     *
     * @param millisToAdvance the number of millis to advance.
     * @return a long representing the current simulated time in millis
     */
    public long advanceTimeMillis(long millisToAdvance) {
        return timerKeeper.advanceTimeMillis(millisToAdvance);
    }

    /**
     * Advances the virtual time a certain number of millis triggers execution delays a certain amount to
     * allow time for execution.  If runLocally is true then all real time delays are ignored.
     *
     * @param virtualTimeAdvance the time to be advances in millis of simulated time.
     * @param realTimeDelay      the time to delay in real time to allow for processing.
     */
    public void advanceTimeMillis(long virtualTimeAdvance, int realTimeDelay) {
        timerKeeper.advanceTimeMillis(virtualTimeAdvance);
        if (!runLocally) {
            delay(realTimeDelay);
        }
    }

    /**
     * Sets up the task and submits it to the queue.
     *
     * @param task    the task to be added to the queue
     * @param runtime the first runtime of the task
     * @param period  the period between runs thereafter
     * @return returns true if the task was successfully submitted, false otherwise
     */
    private boolean submitTask(TimerTask task, long runtime, long period) {
        checkNotNull(task);
        try {
            TestUtils.setField(task, "state", scheduledState);
            TestUtils.setField(task, "nextExecutionTime", runtime);
            TestUtils.setField(task, "period", period);
        } catch (TestUtils.TestUtilsException e) {
            e.printStackTrace();
            return false;
        }
        queue.insertOrdered(task);
        return true;
    }

    /**
     * Executes the given task (only if it is in the scheduled state) and proceeds to reschedule it or mark it as
     * executed.  Does not remove from the queue (this must be done outside).
     *
     * @param task the timer task to be executed
     */
    private boolean executeTask(TimerTask task) {
        checkNotNull(task);
        int currentState;
        try {
            currentState = TestUtils.getField(task, "state");
        } catch (TestUtils.TestUtilsException e) {
            logger.error("Could not get state of task.");
            e.printStackTrace();
            return false;
        }
        //If cancelled or already executed stop here.
        if (currentState == executedState || currentState == cancelledState) {
            return false;
        } else if (currentState == virginState) {
            logger.error("Task was set for execution without being scheduled.");
            return false;
        } else if (currentState == scheduledState) {
            long period;

            try {
                period = TestUtils.getField(task, "period");
            } catch (TestUtils.TestUtilsException e) {
                logger.error("Could not read period of task.");
                e.printStackTrace();
                return false;
            }
            //Period of zero means one time execution.
            if (period == 0) {
                try {
                    TestUtils.setField(task, "state", executedState);
                } catch (TestUtils.TestUtilsException e) {
                    logger.error("Could not set executed state.");
                    e.printStackTrace();
                    return false;
                }
                if (runLocally) {
                    task.run();
                } else {
                    executorService.execute(task);
                }
                return true;
            } else {
                //Calculate next execution time, using absolute value of period
                long nextTime = (period > 0) ? (timerKeeper.currentTimeInMillis() + period) :
                        (timerKeeper.currentTimeInMillis() - period);
                try {
                    TestUtils.setField(task, "nextExecutionTime", nextTime);
                } catch (TestUtils.TestUtilsException e) {
                    logger.error("Could not set next execution time.");
                    e.printStackTrace();
                    return false;
                }
                //Schedule next execution
                queue.insertOrdered(task);
                if (runLocally) {
                    task.run();
                } else {
                    executorService.execute(task);
                }
                return true;
            }
        }
        logger.error("State property of {} is in an illegal state and did not execute.", task);
        return false;
    }

    /**
     * Executes all tasks in the queue scheduled for execution up to and including the current time.
     *
     * @return the total number of tasks run, -1 if failure
     */
    private int executeEventsUpToPresent() {
        int totalRun = 0;
        if (queue.isEmpty()) {
            return -1;
        }
        TimerTask currTask = queue.peek();
        long currExecTime;
        try {
            currExecTime = TestUtils.getField(currTask, "nextExecutionTime");
        } catch (TestUtils.TestUtilsException e) {
            e.printStackTrace();
            throw new RuntimeException("Could not get nextExecutionTime");
        }
        while (currExecTime <= timerKeeper.currentTimeInMillis()) {
            if (executeTask(queue.pop())) {
                totalRun++;
            }
            if (queue.isEmpty()) {
                break;
            }
            currTask = queue.peek();
            try {
                currExecTime = TestUtils.getField(currTask, "nextExecutionTime");
            } catch (TestUtils.TestUtilsException e) {
                e.printStackTrace();
                throw new RuntimeException("Could not get nextExecutionTime");
            }
        }
        return totalRun;
    }

    /**
     * Populates the static fields from timer task. Should only be called once.
     */
    private void populateStatics(TimerTask task) {
        try {
            virginState = TestUtils.getField(task, "VIRGIN");
            scheduledState = TestUtils.getField(task, "SCHEDULED");
            executedState = TestUtils.getField(task, "EXECUTED");
            cancelledState = TestUtils.getField(task, "CANCELLED");
            staticsPopulated = true;
        } catch (TestUtils.TestUtilsException e) {
            e.printStackTrace();
        }
    }

    /**
     * A class used to maintain the virtual time.
     */
    private class TimerKeeper {

        private long currentTime = 0;

        /**
         * Returns the virtual current time in millis.
         *
         * @return long representing simulated current time.
         */
        long currentTimeInMillis() {
            return currentTime;
        }

        /**
         * Returns the new simulated current time in millis after advancing the absolute value of millis to advance.
         * Triggers event execution of all events scheduled for execution at times up to and including the returned
         * time. Passing in the number zero has no effect.
         *
         * @param millisToAdvance the number of millis to advance.
         * @return a long representing the current simulated time in millis
         */
        long advanceTimeMillis(long millisToAdvance) {
            currentTime = (millisToAdvance >= 0) ? (currentTime + millisToAdvance) : (currentTime - millisToAdvance);
            if (millisToAdvance != 0) {
                executeEventsUpToPresent();
            }
            return currentTime;
        }
    }

    /**
     * A queue backed by a linked list. Keeps elements sorted in ascending order of execution time.  All calls are safe
     * even on empty queue's.
     */
    private class TaskQueue {
        private final LinkedList<TimerTask> taskList = Lists.newLinkedList();

        /**
         * Adds the task to the queue in ascending order of scheduled execution. If execution time has already passed
         * execute immediately.
         *
         * @param task the task to be added to the queue
         */
        void insertOrdered(TimerTask task) {
            //Using O(N) insertion because random access is expensive in linked lists worst case is 2N links followed
            // for binary insertion vs N for simple insertion.
            checkNotNull(task);
            if (!staticsPopulated) {
                populateStatics(task);
            }
            long insertTime;
            try {
                insertTime = TestUtils.getField(task, "nextExecutionTime");
                TestUtils.setField(task, "state", scheduledState);
            } catch (TestUtils.TestUtilsException e) {
                e.printStackTrace();
                return;
            }
            //If the task was scheduled in the past or for the current time run it immediately and do not add to the
            // queue, subsequent executions will be scheduled as normal
            if (insertTime <= timerKeeper.currentTimeInMillis()) {
                executeTask(task);
                return;
            }

            Iterator<TimerTask> iter = taskList.iterator();
            int positionCounter = 0;
            long nextTaskTime;
            TimerTask currentTask;
            while (iter.hasNext()) {
                currentTask = iter.next();
                try {
                    nextTaskTime = TestUtils.getField(currentTask, "nextExecutionTime");
                } catch (TestUtils.TestUtilsException e) {
                    e.printStackTrace();
                    return;
                }
                if (insertTime < nextTaskTime) {
                    taskList.add(positionCounter, task);
                    return;
                }
                positionCounter++;
            }
            taskList.addLast(task);
        }

        /**
         * Returns the first item in the queue (next scheduled for execution) without removing it, returns null if the
         * queue is empty.
         *
         * @return the next TimerTask to run or null if the queue is empty
         */
        TimerTask peek() {
            if (taskList.isEmpty()) {
                return null;
            }
            return taskList.getFirst();
        }

        /**
         * Returns and removes the first item in the queue or null if it is empty.
         *
         * @return the first element of the queue or null if the queue is empty
         */
        TimerTask pop() {
            if (taskList.isEmpty()) {
                return null;
            }
            return taskList.pop();
        }

        /**
         * Performs a sort on the set of timer tasks, earliest task is first. Does nothing if queue is empty.
         */
        void sort() {
            if (taskList.isEmpty()) {
                return;
            }
            taskList.sort((o1, o2) -> {
                checkNotNull(o1);
                checkNotNull(o2);
                long executionTimeOne;
                long executionTimeTwo;
                try {
                    executionTimeOne = TestUtils.getField(o1, "nextExecutionTime");
                    executionTimeTwo = TestUtils.getField(o2, "nextExecutionTime");
                } catch (TestUtils.TestUtilsException e) {
                    e.printStackTrace();
                    throw new RuntimeException("Could not get next execution time.");
                }
                if (executionTimeOne == executionTimeTwo) {
                    return 0;
                } else if (executionTimeOne < executionTimeTwo) {
                    return -1;
                } else {
                    return 1;
                }
            });
        }

        /**
         * Returns whether the queue is currently empty.
         *
         * @return true if the queue is empty, false otherwise
         */
        boolean isEmpty() {
            return taskList.isEmpty();
        }

        /**
         * Clears the underlying list of the queue.
         */
        void clear() {
            taskList.clear();
        }

        /**
         * Removes all cancelled tasks from the queue. Has no effect on behavior.
         *
         * @return returns the total number of items removed, -1 if list is empty or failure occurs.
         */
        int removeCancelled() {
            if (taskList.isEmpty()) {
                return -1;
            }
            int removedCount = 0;
            Iterator<TimerTask> taskIterator = taskList.iterator();
            TimerTask currTask;
            int currState;
            while (taskIterator.hasNext()) {
                currTask = taskIterator.next();
                try {
                    currState = TestUtils.getField(currTask, "state");
                } catch (TestUtils.TestUtilsException e) {
                    logger.error("Could not get task state.");
                    e.printStackTrace();
                    return -1;
                }
                if (currState == cancelledState) {
                    removedCount++;
                    taskIterator.remove();
                }
            }
            return removedCount;
        }
    }
}
