/*
 * Copyright 2011-2023 MicroEJ Corp. All rights reserved.
 * This library is provided in source code for use, modification and test, subject to license terms.
 * Any modification of the source code will break MicroEJ Corp. warranties on the whole library.
 */
package ej.bon;

import java.io.PrintStream;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.Date;
import ej.annotation.Nullable;

/**
 * A facility for threads to schedule tasks for future execution in a background
 * thread. Tasks may be scheduled for one-time execution, or for repeated
 * execution at regular intervals.
 * <p>
 * Corresponding to each Timer object is a single background thread that is used
 * to execute all of the timer's tasks, sequentially. Timer tasks should
 * complete quickly. If a timer task takes excessive time to complete, it "hogs"
 * the timer's task execution thread. This can, in turn, delay the execution of
 * subsequent tasks, which may "bunch up" and execute in rapid succession when
 * (and if) the offending task finally completes.
 * <p>
 * By default, the task execution thread does not run as a daemon thread, so it
 * is capable of keeping an application from terminating. If a caller wants to
 * terminate a timer's task execution thread, the caller should invoke the
 * timer's cancel method.
 * <p>
 * If a task execution terminates unexpectedly, the uncaughtException method is
 * invoked on this task.
 * <p>
 * This class is thread-safe: multiple threads can share a single Timer object
 * without the need for external synchronization.
 * <p>
 * This class does not offer real-time guarantees: it schedules tasks using the
 * Object.wait(long) method. The resolution of the Timer is implementation and
 * device dependent.
 * <p>
 * Timers function only within a single VM and are canceled when the VM exits.
 * When the VM is started no timers exist, they are created only by application
 * request.
 */
public class Timer {

    /**
     * Creates a new timer. The associated thread does not run as a daemon thread,
     * which may prevent an application from terminating.
     */
    public Timer() {
        throw new RuntimeException();
    }

    /**
     * Creates a new timer.
     * <p>
     * If the given boolean is <code>true</code>, a thread is created to execute
     * this timer. The associated thread does not run as a daemon thread, which may
     * prevent an application from terminating. All the {@link TimerTask} scheduled
     * by the timer will be executed in the context of the associated thread.
     * <p>
     * Otherwise an applicative thread must call the {@link #run()} method in order
     * to execute tasks scheduling.
     *
     * @param automatic
     *            If <code>true</code> a thread is created to run this timer,
     *            otherwise the application must manage this timer.
     * @see #run()
     */
    public Timer(boolean automatic) {
        throw new RuntimeException();
    }

    /**
     * Schedules the specified task for execution after the specified delay.
     *
     * @param task
     *            task to be scheduled.
     * @param delay
     *            delay in milliseconds before task is to be executed. Note that the
     *            actual delay may be different from the amount requested since the
     *            resolution of the Timer is implementation and device dependent.
     * @throws IllegalArgumentException
     *             if delay is negative, or delay + CurrentTime.get() is negative.
     * @throws IllegalStateException
     *             if task was already scheduled or canceled, or timer was canceled.
     */
    public void schedule(TimerTask task, long delay) {
        throw new RuntimeException();
    }

    /**
     * Schedules the specified task for execution at the specified time. If the time
     * is in the past, the task is scheduled for immediate execution.
     *
     * @param task
     *            task to be scheduled.
     * @param time
     *            time at which task is to be executed.
     * @throws IllegalArgumentException
     *             if time.getTime() is negative.
     * @throws IllegalStateException
     *             if task was already scheduled or canceled, timer was canceled, or
     *             timer thread terminated.
     */
    public void schedule(TimerTask task, Date time) {
        throw new RuntimeException();
    }

    /**
     * Schedules the specified task for repeated fixed-delay execution, beginning
     * after the specified delay. Subsequent executions take place at approximately
     * regular intervals separated by the specified period. Note that the actual
     * delay may be different from the amount requested since the resolution of the
     * Timer is implementation and device dependent.
     * <p>
     * In fixed-delay execution, each execution is scheduled relative to the actual
     * execution time of the previous execution. If an execution is delayed for any
     * reason (such as garbage collection or other background activity), subsequent
     * executions will be delayed as well. In the long run, the frequency of
     * execution will generally be slightly lower than the reciprocal of the
     * specified period (assuming the system clock underlying Object.wait(long) is
     * accurate).
     * <p>
     * Fixed-delay execution is appropriate for recurring activities that require
     * "smoothness." In other words, it is appropriate for activities where it is
     * more important to keep the frequency accurate in the short run than in the
     * long run. This includes most animation tasks, such as blinking a cursor at
     * regular intervals. It also includes tasks wherein regular activity is
     * performed in response to human input, such as automatically repeating a
     * character as long as a key is held down.
     *
     * @param task
     *            task to be scheduled.
     * @param delay
     *            delay in milliseconds before task is to be executed. Note that the
     *            actual delay may be different from the amount requested since the
     *            resolution of the Timer is implementation and device dependent.
     * @param period
     *            time in milliseconds between successive task executions.
     *
     * @throws IllegalArgumentException
     *             if delay is negative, or delay + CurrentTime.get() is negative.
     * @throws IllegalStateException
     *             if task was already scheduled or canceled, timer was canceled, or
     *             timer thread terminated.
     */
    public void schedule(TimerTask task, long delay, long period) {
        throw new RuntimeException();
    }

    /**
     * Schedules the specified task for repeated fixed-delay execution, beginning at
     * the specified time. Subsequent executions take place at approximately regular
     * intervals, separated by the specified period.
     * <p>
     * In fixed-delay execution, each execution is scheduled relative to the actual
     * execution time of the previous execution. If an execution is delayed for any
     * reason (such as garbage collection or other background activity), subsequent
     * executions will be delayed as well. In the long run, the frequency of
     * execution will generally be slightly lower than the reciprocal of the
     * specified period (assuming the system clock underlying Object.wait(long) is
     * accurate).
     * <p>
     * Fixed-delay execution is appropriate for recurring activities that require
     * "smoothness." In other words, it is appropriate for activities where it is
     * more important to keep the frequency accurate in the short run than in the
     * long run. This includes most animation tasks, such as blinking a cursor at
     * regular intervals. It also includes tasks wherein regular activity is
     * performed in response to human input, such as automatically repeating a
     * character as long as a key is held down.
     *
     * @param task
     *            task to be scheduled.
     * @param firstTime
     *            First time at which task is to be executed.
     * @param period
     *            time in milliseconds between successive task executions.
     *
     * @throws IllegalArgumentException
     *             if time.getTime() is negative.
     * @throws IllegalStateException
     *             if task was already scheduled or canceled, timer was canceled, or
     *             timer thread terminated.
     */
    public void schedule(TimerTask task, Date firstTime, long period) {
        throw new RuntimeException();
    }

    /**
     * Schedules the specified task for repeated fixed-rate execution, beginning
     * after the specified delay. Subsequent executions take place at approximately
     * regular intervals, separated by the specified period.
     * <p>
     * In fixed-rate execution, each execution is scheduled relative to the
     * scheduled execution time of the initial execution. If an execution is delayed
     * for any reason (such as garbage collection or other background activity), two
     * or more executions will occur in rapid succession to "catch up." In the long
     * run, the frequency of execution will be exactly the reciprocal of the
     * specified period (assuming the system clock underlying Object.wait(long) is
     * accurate).
     * <p>
     * Fixed-rate execution is appropriate for recurring activities that are
     * sensitive to absolute time, such as ringing a chime every hour on the hour,
     * or running scheduled maintenance every day at a particular time. It is also
     * appropriate for for recurring activities where the total time to perform a
     * fixed number of executions is important, such as a countdown timer that ticks
     * once every second for ten seconds. Finally, fixed-rate execution is
     * appropriate for scheduling multiple repeating timer tasks that must remain
     * synchronized with respect to one another.
     *
     * @param task
     *            task to be scheduled.
     * @param delay
     *            delay in milliseconds before task is to be executed. Note that the
     *            actual delay may be different from the amount requested since the
     *            resolution of the Timer is implementation and device dependent.
     * @param period
     *            time in milliseconds between successive task executions.
     *
     * @throws IllegalArgumentException
     *             if delay is negative, or delay + CurrentTime.get() is negative.
     * @throws IllegalStateException
     *             if task was already scheduled or canceled, timer was canceled, or
     *             timer thread terminated.
     */
    public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
        throw new RuntimeException();
    }

    /**
     * Schedules the specified task for repeated fixed-rate execution, beginning at
     * the specified time. Subsequent executions take place at approximately regular
     * intervals, separated by the specified period.
     * <p>
     * In fixed-rate execution, each execution is scheduled relative to the
     * scheduled execution time of the initial execution. If an execution is delayed
     * for any reason (such as garbage collection or other background activity), two
     * or more executions will occur in rapid succession to "catch up." In the long
     * run, the frequency of execution will be exactly the reciprocal of the
     * specified period (assuming the system clock underlying Object.wait(long) is
     * accurate).
     * <p>
     * Fixed-rate execution is appropriate for recurring activities that are
     * sensitive to absolute time, such as ringing a chime every hour on the hour,
     * or running scheduled maintenance every day at a particular time. It is also
     * appropriate for for recurring activities where the total time to perform a
     * fixed number of executions is important, such as a countdown timer that ticks
     * once every second for ten seconds. Finally, fixed-rate execution is
     * appropriate for scheduling multiple repeating timer tasks that must remain
     * synchronized with respect to one another.
     *
     * @param task
     *            task to be scheduled.
     * @param firstTime
     *            first time at which task is to be executed.
     * @param period
     *            time in milliseconds between successive task executions.
     *
     * @throws IllegalArgumentException
     *             if time.getTime() is negative.
     * @throws IllegalStateException
     *             if task was already scheduled or canceled, timer was canceled, or
     *             timer thread terminated.
     */
    public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period) {
        throw new RuntimeException();
    }

    /**
     * Terminates this timer, discarding any currently scheduled tasks. Does not
     * interfere with a currently executing task (if it exists). Once a timer has
     * been terminated, its execution thread terminates gracefully, and no more
     * tasks may be scheduled on it.
     *
     * Note that calling this method from within the run method of a timer task that
     * was invoked by this timer absolutely guarantees that the ongoing task
     * execution is the last task execution that will ever be performed by this
     * timer.
     */
    public void cancel() {
        throw new RuntimeException();
    }

    /**
     * Executes {@link TimerTask} scheduling. This method must be called only for
     * {@link Timer} that are not automatic (i.e. no thread is automatically started
     * at {@link Timer} creation). This is the current thread that executes the
     * {@link Timer} scheduling loop.
     * <p>
     * This method can be called once on this {@link Timer} and returns only if
     * {@link #cancel()} is called.
     *
     * @throws IllegalStateException
     *             if this timer is already running or canceled.
     */
    public void run() {
        throw new RuntimeException();
    }

    /**
     * Sets the default handler for uncaught exceptions.
     *
     * @param h
     *            the new default handler, or <code>null</code> to remove the
     *            default {@link Timer} class handler.
     *
     * @throws SecurityException
     *             if a security manager exists and it denies
     *             <tt>{@link RuntimePermission}
     *         (&quot;setDefaultUncaughtExceptionHandler&quot;)</tt>
     *
     * @see #setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler)
     * @see TimerTask#uncaughtException(Timer, Throwable)
     */
    public static void setDefaultUncaughtExceptionHandler(@Nullable UncaughtExceptionHandler h) {
        throw new RuntimeException();
    }

    /**
     * Gets the default registered handler for uncaught exceptions.
     *
     * @return the default handler, or <code>null</code> if there is no default
     *         handler registered.
     * @see #setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler)
     * @see TimerTask#uncaughtException(Timer, Throwable)
     */
    @Nullable
    public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() {
        throw new RuntimeException();
    }

    /**
     * Sets the specific handler for uncaught exceptions on this {@link Timer}
     * instance.
     *
     * @param h
     *            the new handler, or <code>null</code> to remove the specific
     *            {@link Timer} handler.
     *
     * @see #setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler)
     * @see TimerTask#uncaughtException(Timer, Throwable)
     */
    public void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler h) {
        throw new RuntimeException();
    }

    /**
     * Gets the specific handler for uncaught exceptions on this {@link Timer}
     * instance.
     *
     * @return the handler, or <code>null</code> if there no registered handler.
     * @see TimerTask#uncaughtException(Timer, Throwable)
     */
    @Nullable
    public Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() {
        throw new RuntimeException();
    }

    /**
     * Prints a status of this timer and its scheduled tasks to the specified print
     * stream. This method is used only for debugging.
     *
     * @param s
     *        {@code PrintStream} to use for output.
     */
    public void dump(PrintStream s) {
        throw new RuntimeException();
    }
}
