/*
 * Copyright 2015 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;
        }
    }
}
