/*
 * 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();

    @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.
     *
     * @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);
        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;
                }
                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);
                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;
        }
    }
}
