/*
 * 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.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Date;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicInteger;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.onlab.junit.TestTools.delay;

/**
 * Testing class for manually advancing timer.
 */
public class ManuallyAdvancingTimerTest {

    private ManuallyAdvancingTimer timer;

    /* Generates unique id's for TestTasks */
    private AtomicInteger idGenerator;

    /* Tracks TestTasks in order of creation, tasks are automatically added at creation. */
    private ArrayList<TestTask> taskList;

    /* Total number of tasks run */
    private AtomicInteger tasksRunCount;

    // FIXME if this class fails first try increasing the real time delay to account for heavy system load.
    private static final int REAL_TIME_DELAY = 10;

    /**
     * Sets up the testing environment.
     */
    @Before
    public void setup() {
        timer = new ManuallyAdvancingTimer(true);
        idGenerator = new AtomicInteger(1);
        tasksRunCount = new AtomicInteger(0);
        taskList = Lists.newArrayList();
    }

    /**
     * Tests the one time schedule with delay.
     *
     * @throws Exception throws an exception if the test fails
     */
    @Test
    public void testScheduleByDelay() throws Exception {
        /* Test scheduling in the future as normal. */
        timer.schedule(new TestTask(), 10);
        timer.advanceTimeMillis(5);
        assertFalse(taskList.get(0).hasRun());
        timer.advanceTimeMillis(10, REAL_TIME_DELAY);
        assertTrue(taskList.get(0).hasRun());

        /* Test scheduling with negative numbers */
        timer.schedule(new TestTask(), -10);
        timer.advanceTimeMillis(5);
        assertFalse(taskList.get(1).hasRun());
        timer.advanceTimeMillis(10, REAL_TIME_DELAY);
        assertTrue(taskList.get(1).hasRun());

        /* Reset list, counter and timer for next test */
        taskList.clear();
        idGenerator.set(1);
        tasksRunCount.set(0);

        for (int i = 0; i < 50; i++) {
            timer.schedule(new TestTask(), i);
        }
        /* Test that a task scheduled for present is run and not placed in the queue */
        assertEquals("Only the first task should have run.", 1, tasksRunCount.get());

        for (int i = 2; i <= 50; i++) {
            timer.advanceTimeMillis(1, REAL_TIME_DELAY);
            assertEquals("One task should be executed per loop", i, tasksRunCount.get());
        }
        /* Below tests ordered insertion, this will only be done once, it is the same for all schedule methods. */

        tasksRunCount.set(0);

        for (int i = 0; i < 10; i++) {
            timer.schedule(new TestTask(), 500);
        }

        assertEquals("No new tasks should have been run  since run count reset.", 0, tasksRunCount.get());
        timer.schedule(new TestTask(), 10);
        assertEquals("No new tasks should have been run  since run count reset.", 0, tasksRunCount.get());
        timer.advanceTimeMillis(10, REAL_TIME_DELAY);
        assertEquals("One new tasks should have been run  since run count reset.", 1, tasksRunCount.get());
        timer.advanceTimeMillis(510, REAL_TIME_DELAY);
        assertEquals("Eleven new tasks should have been run  since run count reset.", 11, tasksRunCount.get());
    }

    /**
     * Tests scheduling for a particular date or time which may be in the past.
     *
     * @throws Exception throws an exception if the test fails
     */
    @Test
    public void testScheduleByDate() throws Exception {
        /* Tests basic scheduling for future times. */
        timer.schedule(new TestTask(), new Date(10));
        timer.advanceTimeMillis(5);
        assertFalse(taskList.get(0).hasRun());
        timer.advanceTimeMillis(10, REAL_TIME_DELAY);
        assertTrue(taskList.get(0).hasRun());

        /* Test scheduling with past times numbers */
        timer.schedule(new TestTask(), new Date(0));
        delay(REAL_TIME_DELAY);
        assertTrue(taskList.get(1).hasRun());

        /* Tests cancellation on non-periodic events */
        TestTask task = new TestTask();
        timer.schedule(task, new Date(timer.currentTimeInMillis() + 10));
        task.cancel();
        timer.advanceTimeMillis(12, REAL_TIME_DELAY);
        assertFalse(task.hasRun());

    }

    /**
     * Test scheduling beginning after a delay and recurring periodically.
     *
     * @throws Exception throws an exception if the test fails
     */
    @Test
    public void testScheduleByDelayPeriodic() throws Exception {
        /* Test straightforward periodic execution */
        timer.schedule(new TestTask(), 0, 10);
        delay(REAL_TIME_DELAY);
        assertEquals("Task should have run once when added.", 1, taskList.get(0).timesRun());

        /* Tests whether things that are not added to the queue are scheduled for future executions (ones which execute
        immediately on add). */
        timer.advanceTimeMillis(10, REAL_TIME_DELAY);
        assertEquals("Task should have run once when added.", 2, taskList.get(0).timesRun());

        /* Tests whether cancellation works on periodic events. */
        taskList.get(0).cancel();

        timer.advanceTimeMillis(10, REAL_TIME_DELAY);
        assertEquals("The task should not have run another time.", 2, taskList.get(0).timesRun());

        TestTask task = new TestTask();
        timer.schedule(task, 0, 10);
        timer.advanceTimeMillis(100, REAL_TIME_DELAY);
        assertEquals("Should have run immeditaley and subsequently once during the larger skip", task.timesRun(), 2);

    }

    /**
     * Test scheduling beginning at a specified date and recurring periodically.
     *
     * @throws Exception throws an exception if the test fails
     */
    @Test
    public void testScheduleByDatePeriodic() throws Exception {
        /* Test straightforward periodic execution */
        timer.schedule(new TestTask(), new Date(timer.currentTimeInMillis()), 10);
        delay(REAL_TIME_DELAY);
        assertEquals("Task should have run once when added.", 1, taskList.get(0).timesRun());

        /* Tests whether things that are not added to the queue are scheduled for future executions (ones which execute
        immediately on add). */
        timer.advanceTimeMillis(10, REAL_TIME_DELAY);
        assertEquals("Task should have run once when added.", 2, taskList.get(0).timesRun());

        /* Tests whether cancellation works on periodic events. */
        taskList.get(0).cancel();

        timer.advanceTimeMillis(10, REAL_TIME_DELAY);
        assertEquals("The task should not have run another time.", 2, taskList.get(0).timesRun());

        TestTask task = new TestTask();
        timer.schedule(task, new Date(timer.currentTimeInMillis()), 10);
        timer.advanceTimeMillis(100, REAL_TIME_DELAY);
        assertEquals("Should have run immediately and subsequently once during the larger skip", task.timesRun(), 2);
    }

    /* Schedule at fixed rate runs exactly like the two scheduling methods just tested so tests are not included */

    /**
     * Timer task with added functions to make it better for testing.
     */
    private class TestTask extends TimerTask {

        /* Remains true once the task has been run at least once */
        private boolean hasRun;

        /* Unique id per event. */
        private int id;

        /* Specifies the number of times an event has run */
        private int timesRun;

        /**
         * Constructor initializes id, timesRun, and id fields.
         */
        public TestTask() {
            id = idGenerator.getAndIncrement();
            timesRun = 0;
            hasRun = false;
            taskList.add(this);
        }

        @Override
        public void run() {
            this.hasRun = true;
            tasksRunCount.incrementAndGet();
            timesRun++;
        }

        /**
         * Returns whether this event has run.
         *
         * @return true if the event has run, false otherwise.
         */
        public boolean hasRun() {
            return hasRun;
        }

        /**
         * Returns the number of times this task has run.
         *
         * @return an int representing the number of times this task has been run
         */
        public int timesRun() {
            return timesRun;
        }

        /**
         * Returns the unique identifier of this task.
         *
         * @return a unique integer identifier
         */
        public int getId() {
            return id;
        }
    }
}