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