/* Timer.java -- Timer that runs TimerTasks at a later time.
   Copyright (C) 2000, 2001, 2005 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.util;

/**
 * Timer that can run TimerTasks at a later time.
 * TimerTasks can be scheduled for one time execution at some time in the
 * future. They can be scheduled to be rescheduled at a time period after the
 * task was last executed. Or they can be scheduled to be executed repeatedly
 * at a fixed rate.
 * <p>
 * The normal scheduling will result in a more or less even delay in time
 * between successive executions, but the executions could drift in time if
 * the task (or other tasks) takes a long time to execute. Fixed delay
 * scheduling guarantees more or less that the task will be executed at a
 * specific time, but if there is ever a delay in execution then the period
 * between successive executions will be shorter. The first method of
 * repeated scheduling is preferred for repeated tasks in response to user
 * interaction, the second method of repeated scheduling is preferred for tasks
 * that act like alarms.
 * <p>
 * The Timer keeps a binary heap as a task priority queue which means that
 * scheduling and serving of a task in a queue of n tasks costs O(log n).
 *
 * @see TimerTask
 * @since 1.3
 * @author Mark Wielaard (mark@klomp.org)
 */
public class Timer
{
  /**
   * Priority Task Queue.
   * TimerTasks are kept in a binary heap.
   * The scheduler calls sleep() on the queue when it has nothing to do or
   * has to wait. A sleeping scheduler can be notified by calling interrupt()
   * which is automatically called by the enqueue(), cancel() and
   * timerFinalized() methods.
   */
  private static final class TaskQueue
  {
    /** Default size of this queue */
    private static final int DEFAULT_SIZE = 32;

    /** Whether to return null when there is nothing in the queue */
    private boolean nullOnEmpty;

    /**
     * The heap containing all the scheduled TimerTasks
     * sorted by the TimerTask.scheduled field.
     * Null when the stop() method has been called.
     */
    private TimerTask heap[];

    /**
     * The actual number of elements in the heap
     * Can be less then heap.length.
     * Note that heap[0] is used as a sentinel.
     */
    private int elements;

    /**
     * Creates a TaskQueue of default size without any elements in it.
     */
    public TaskQueue()
    {
      heap = new TimerTask[DEFAULT_SIZE];
      elements = 0;
      nullOnEmpty = false;
    }

    /**
     * Adds a TimerTask at the end of the heap.
     * Grows the heap if necessary by doubling the heap in size.
     */
    private void add(TimerTask task)
    {
      elements++;
      if (elements == heap.length)
        {
          TimerTask new_heap[] = new TimerTask[heap.length * 2];
          System.arraycopy(heap, 0, new_heap, 0, heap.length);
          heap = new_heap;
        }
      heap[elements] = task;
    }

    /**
     * Removes the last element from the heap.
     * Shrinks the heap in half if
     * elements+DEFAULT_SIZE/2 <= heap.length/4.
     */
    private void remove()
    {
      // clear the entry first
      heap[elements] = null;
      elements--;
      if (elements + DEFAULT_SIZE / 2 <= (heap.length / 4))
        {
          TimerTask new_heap[] = new TimerTask[heap.length / 2];
          System.arraycopy(heap, 0, new_heap, 0, elements + 1);
          heap = new_heap;
        }
    }

    /**
     * Adds a task to the queue and puts it at the correct place
     * in the heap.
     */
    public synchronized void enqueue(TimerTask task)
    {
      // Check if it is legal to add another element
      if (heap == null)
        {
          throw new IllegalStateException
            ("cannot enqueue when stop() has been called on queue");
        }

      heap[0] = task;           // sentinel
      add(task);                // put the new task at the end
      // Now push the task up in the heap until it has reached its place
      int child = elements;
      int parent = child / 2;
      while (heap[parent].scheduled > task.scheduled)
        {
          heap[child] = heap[parent];
          child = parent;
          parent = child / 2;
        }
      // This is the correct place for the new task
      heap[child] = task;
      heap[0] = null;           // clear sentinel
      // Maybe sched() is waiting for a new element
      this.notify();
    }

    /**
     * Returns the top element of the queue.
     * Can return null when no task is in the queue.
     */
    private TimerTask top()
    {
      if (elements == 0)
        {
          return null;
        }
      else
        {
          return heap[1];
        }
    }

    /**
     * Returns the top task in the Queue.
     * Removes the element from the heap and reorders the heap first.
     * Can return null when there is nothing in the queue.
     */
    public synchronized TimerTask serve()
    {
      // The task to return
      TimerTask task = null;

      while (task == null)
        {
          // Get the next task
          task = top();

          // return null when asked to stop
          // or if asked to return null when the queue is empty
          if ((heap == null) || (task == null && nullOnEmpty))
            {
              return null;
            }

          // Do we have a task?
          if (task != null)
            {
              // The time to wait until the task should be served
              long time = task.scheduled - System.currentTimeMillis();
              if (time > 0)
                {
                  // This task should not yet be served
                  // So wait until this task is ready
                  // or something else happens to the queue
                  task = null;  // set to null to make sure we call top()
                  try
                    {
                      this.wait(time);
                    }
                  catch (InterruptedException _)
                    {
                    }
                }
            }
          else
            {
              // wait until a task is added
              // or something else happens to the queue
              try
                {
                  this.wait();
                }
              catch (InterruptedException _)
                {
                }
            }
        }

      // reconstruct the heap
      TimerTask lastTask = heap[elements];
      remove();

      // drop lastTask at the beginning and move it down the heap
      int parent = 1;
      int child = 2;
      heap[1] = lastTask;
      while (child <= elements)
        {
          if (child < elements)
            {
              if (heap[child].scheduled > heap[child + 1].scheduled)
                {
                  child++;
                }
            }

          if (lastTask.scheduled <= heap[child].scheduled)
            break;              // found the correct place (the parent) - done

          heap[parent] = heap[child];
          parent = child;
          child = parent * 2;
        }

      // this is the correct new place for the lastTask
      heap[parent] = lastTask;

      // return the task
      return task;
    }

    /**
     * When nullOnEmpty is true the serve() method will return null when
     * there are no tasks in the queue, otherwise it will wait until
     * a new element is added to the queue. It is used to indicate to
     * the scheduler that no new tasks will ever be added to the queue.
     */
    public synchronized void setNullOnEmpty(boolean nullOnEmpty)
    {
      this.nullOnEmpty = nullOnEmpty;
      this.notify();
    }

    /**
     * When this method is called the current and all future calls to
     * serve() will return null. It is used to indicate to the Scheduler
     * that it should stop executing since no more tasks will come.
     */
    public synchronized void stop()
    {
      this.heap = null;
      this.elements = 0;
      this.notify();
    }

    /**
     * Remove all canceled tasks from the queue.
     */
    public synchronized int purge()
    {
      int removed = 0;
      // Null out any elements that are canceled.  Skip element 0 as
      // it is the sentinel.
      for (int i = elements; i > 0; --i)
        {
          if (heap[i].scheduled < 0)
            {
              ++removed;

              // Remove an element by pushing the appropriate child
              // into place, and then iterating to the bottom of the
              // tree.
              int index = i;
              while (heap[index] != null)
                {
                  int child = 2 * index;
                  if (child >= heap.length)
                    {
                      // Off end; we're done.
                      heap[index] = null;
                      break;
                    }

                  if (child + 1 >= heap.length || heap[child + 1] == null)
                    {
                      // Nothing -- we're done.
                    }
                  else if (heap[child] == null
                           || (heap[child].scheduled
                               > heap[child + 1].scheduled))
                    ++child;
                  heap[index] = heap[child];
                  index = child;
                }
            }
        }

      // Make a new heap if we shrank enough.
      int newLen = heap.length;
      while (elements - removed + DEFAULT_SIZE / 2 <= newLen / 4)
        newLen /= 2;
      if (newLen != heap.length)
        {
          TimerTask[] newHeap = new TimerTask[newLen];
          System.arraycopy(heap, 0, newHeap, 0, elements + 1);
          heap = newHeap;
        }

      return removed;
    }
  }                             // TaskQueue

  /**
   * The scheduler that executes all the tasks on a particular TaskQueue,
   * reschedules any repeating tasks and that waits when no task has to be
   * executed immediately. Stops running when canceled or when the parent
   * Timer has been finalized and no more tasks have to be executed.
   */
  private static final class Scheduler implements Runnable
  {
    // The priority queue containing all the TimerTasks.
    private TaskQueue queue;

    /**
     * Creates a new Scheduler that will schedule the tasks on the
     * given TaskQueue.
     */
    public Scheduler(TaskQueue queue)
    {
      this.queue = queue;
    }

    public void run()
    {
      TimerTask task;
      while ((task = queue.serve()) != null)
        {
          // If this task has not been canceled
          if (task.scheduled >= 0)
            {

              // Mark execution time
              task.lastExecutionTime = task.scheduled;

              // Repeatable task?
              if (task.period < 0)
                {
                  // Last time this task is executed
                  task.scheduled = -1;
                }

              // Run the task
              try
                {
                  task.run();
                }
              catch (ThreadDeath death)
                {
                  // If an exception escapes, the Timer becomes invalid.
                  queue.stop();
                  throw death;
                }
              catch (Throwable t)
                {
                  // If an exception escapes, the Timer becomes invalid.
                  queue.stop();
                }
            }

          // Calculate next time and possibly re-enqueue.
          if (task.scheduled >= 0)
            {
              if (task.fixed)
                {
                  task.scheduled += task.period;
                }
              else
                {
                  task.scheduled = task.period + System.currentTimeMillis();
                }

              try
                {
                  queue.enqueue(task);
                }
              catch (IllegalStateException ise)
                {
                  // Ignore. Apparently the Timer queue has been stopped.
                }
            }
        }
    }
  }                             // Scheduler

  // Number of Timers created.
  // Used for creating nice Thread names.
  private static int nr;

  // The queue that all the tasks are put in.
  // Given to the scheduler
  private TaskQueue queue;

  // The Scheduler that does all the real work
  private Scheduler scheduler;

  // Used to run the scheduler.
  // Also used to checked if the Thread is still running by calling
  // thread.isAlive(). Sometimes a Thread is suddenly killed by the system
  // (if it belonged to an Applet).
  private Thread thread;

  // When cancelled we don't accept any more TimerTasks.
  private boolean canceled;

  /**
   * Creates a new Timer with a non daemon Thread as Scheduler, with normal
   * priority and a default name.
   */
  public Timer()
  {
    this(false);
  }

  /**
   * Creates a new Timer with a daemon Thread as scheduler if daemon is true,
   * with normal priority and a default name.
   */
  public Timer(boolean daemon)
  {
    this(daemon, Thread.NORM_PRIORITY);
  }

  /**
   * Create a new Timer whose Thread has the indicated name.  It will have
   * normal priority and will not be a daemon thread.
   * @param name the name of the Thread
   * @since 1.5
   */
  public Timer(String name)
  {
    this(false, Thread.NORM_PRIORITY, name);
  }

  /**
   * Create a new Timer whose Thread has the indicated name.  It will have
   * normal priority.  The boolean argument controls whether or not it
   * will be a daemon thread.
   * @param name the name of the Thread
   * @param daemon true if the Thread should be a daemon thread
   * @since 1.5
   */
  public Timer(String name, boolean daemon)
  {
    this(daemon, Thread.NORM_PRIORITY, name);
  }

  /**
   * Creates a new Timer with a daemon Thread as scheduler if daemon is true,
   * with the priority given and a default name.
   */
  private Timer(boolean daemon, int priority)
  {
    this(daemon, priority, "Timer-" + (++nr));
  }

  /**
   * Creates a new Timer with a daemon Thread as scheduler if daemon is true,
   * with the priority and name given.E
   */
  private Timer(boolean daemon, int priority, String name)
  {
    canceled = false;
    queue = new TaskQueue();
    scheduler = new Scheduler(queue);
    thread = new Thread(scheduler, name);
    thread.setDaemon(daemon);
    thread.setPriority(priority);
    thread.start();
  }

  /**
   * Cancels the execution of the scheduler. If a task is executing it will
   * normally finish execution, but no other tasks will be executed and no
   * more tasks can be scheduled.
   */
  public void cancel()
  {
    canceled = true;
    queue.stop();
  }

  /**
   * Schedules the task at Time time, repeating every period
   * milliseconds if period is positive and at a fixed rate if fixed is true.
   *
   * @exception IllegalArgumentException if time is negative
   * @exception IllegalStateException if the task was already scheduled or
   * canceled or this Timer is canceled or the scheduler thread has died
   */
  private void schedule(TimerTask task, long time, long period, boolean fixed)
  {
    if (time < 0)
      throw new IllegalArgumentException("negative time");

    if (task.scheduled == 0 && task.lastExecutionTime == -1)
      {
        task.scheduled = time;
        task.period = period;
        task.fixed = fixed;
      }
    else
      {
        throw new IllegalStateException
          ("task was already scheduled or canceled");
      }

    if (!this.canceled && this.thread != null)
      {
        queue.enqueue(task);
      }
    else
      {
        throw new IllegalStateException
          ("timer was canceled or scheduler thread has died");
      }
  }

  private static void positiveDelay(long delay)
  {
    if (delay < 0)
      {
        throw new IllegalArgumentException("delay is negative");
      }
  }

  private static void positivePeriod(long period)
  {
    if (period < 0)
      {
        throw new IllegalArgumentException("period is negative");
      }
  }

  /**
   * Schedules the task at the specified data for one time execution.
   *
   * @exception IllegalArgumentException if date.getTime() is negative
   * @exception IllegalStateException if the task was already scheduled or
   * canceled or this Timer is canceled or the scheduler thread has died
   */
  public void schedule(TimerTask task, Date date)
  {
    long time = date.getTime();
    schedule(task, time, -1, false);
  }

  /**
   * Schedules the task at the specified date and reschedules the task every
   * period milliseconds after the last execution of the task finishes until
   * this timer or the task is canceled.
   *
   * @exception IllegalArgumentException if period or date.getTime() is
   * negative
   * @exception IllegalStateException if the task was already scheduled or
   * canceled or this Timer is canceled or the scheduler thread has died
   */
  public void schedule(TimerTask task, Date date, long period)
  {
    positivePeriod(period);
    long time = date.getTime();
    schedule(task, time, period, false);
  }

  /**
   * Schedules the task after the specified delay milliseconds for one time
   * execution.
   *
   * @exception IllegalArgumentException if delay or
   * System.currentTimeMillis + delay is negative
   * @exception IllegalStateException if the task was already scheduled or
   * canceled or this Timer is canceled or the scheduler thread has died
   */
  public void schedule(TimerTask task, long delay)
  {
    positiveDelay(delay);
    long time = System.currentTimeMillis() + delay;
    schedule(task, time, -1, false);
  }

  /**
   * Schedules the task after the delay milliseconds and reschedules the
   * task every period milliseconds after the last execution of the task
   * finishes until this timer or the task is canceled.
   *
   * @exception IllegalArgumentException if delay or period is negative
   * @exception IllegalStateException if the task was already scheduled or
   * canceled or this Timer is canceled or the scheduler thread has died
   */
  public void schedule(TimerTask task, long delay, long period)
  {
    positiveDelay(delay);
    positivePeriod(period);
    long time = System.currentTimeMillis() + delay;
    schedule(task, time, period, false);
  }

  /**
   * Schedules the task at the specified date and reschedules the task at a
   * fixed rate every period milliseconds until this timer or the task is
   * canceled.
   *
   * @exception IllegalArgumentException if period or date.getTime() is
   * negative
   * @exception IllegalStateException if the task was already scheduled or
   * canceled or this Timer is canceled or the scheduler thread has died
   */
  public void scheduleAtFixedRate(TimerTask task, Date date, long period)
  {
    positivePeriod(period);
    long time = date.getTime();
    schedule(task, time, period, true);
  }

  /**
   * Schedules the task after the delay milliseconds and reschedules the task
   * at a fixed rate every period milliseconds until this timer or the task
   * is canceled.
   *
   * @exception IllegalArgumentException if delay or
   * System.currentTimeMillis + delay is negative
   * @exception IllegalStateException if the task was already scheduled or
   * canceled or this Timer is canceled or the scheduler thread has died
   */
  public void scheduleAtFixedRate(TimerTask task, long delay, long period)
  {
    positiveDelay(delay);
    positivePeriod(period);
    long time = System.currentTimeMillis() + delay;
    schedule(task, time, period, true);
  }

  /**
   * Tells the scheduler that the Timer task died
   * so there will be no more new tasks scheduled.
   */
  protected void finalize() throws Throwable
  {
    queue.setNullOnEmpty(true);
  }

  /**
   * Removes all cancelled tasks from the queue.
   * @return the number of tasks removed
   * @since 1.5
   */
  public int purge()
  {
    return queue.purge();
  }
}
