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

/**
 * This class gives access to the global immortal objects pool.
 * <p>
 * An immortal object has two major properties:
 * <ol>
 * <li>it is not managed by the garbage collector,</li>
 * <li>it does not move around in memory, i.e. its physical memory location
 * remains the same forever.</li>
 * </ol>
 */
public class Immortals {

	/**
	 * Gets whether an object is immortal or not.
	 * <p>
	 * An object is immortal:
	 * <ul>
	 * <li>if it has been declared as immortal calling
	 * {@link #setImmortal(Object)},</li>
	 * <li>if it is immutable.</li>
	 * </ul>
	 *
	 * @param o
	 *            the object to check
	 * @return <code>true</code> if the queried object is immortal or immutable,
	 *         <code>false</code> otherwise
	 * @throws NullPointerException
	 *             if given object is null
	 * @see Immutables#isImmutable(Object)
	 */
	public static boolean isImmortal(Object o) {
		throw new RuntimeException();
	}

	/**
	 * Turns the given object into an immortal object.
	 * <p>
	 * If the received object was immutable, it remains immutable.
	 * <p>
	 * If the object was already immortal, it remains immortal.
	 * <p>
	 * If the object was a reclaimable object it turns into an immortal object. Upon
	 * success, the returned object is immortal, otherwise an
	 * {@link OutOfMemoryError} is thrown.
	 *
	 * @param <T>
	 *            the object type
	 *
	 * @param o
	 *            the object to turn into an immortal
	 * @return the given object turned into immortal
	 * @throws OutOfMemoryError
	 *             if the immortal memory is full
	 */
	public static <T> T setImmortal(T o) {
		throw new RuntimeException();
	}

	/**
	 * Turns the given object and all objects referred from it into immortal
	 * objects.
	 * <p>
	 * Weakly reachable objects are not turned into immortal objects.
	 *
	 * @param <T>
	 *            the root object type
	 *
	 * @param root
	 *            the root of the objects graph to turn into immortal
	 * @return the given object turned into immortal
	 */
	public static <T> T deepImmortal(T root) {
		throw new RuntimeException();
	}

	/**
	 * Calls the method {@link Runnable#run()} of the given runnable.
	 * <p>
	 * All the objects allocated in the context of this method are directly
	 * allocated as immortals. While the {@link Runnable#run()} method of the
	 * runnable executes all created objects are allocated as immortal objects.
	 *
	 * @param runnable
	 *            the runnable to execute
	 * @throws NullPointerException
	 *             if the given runnable is <code>null</code>
	 */
	public static void run(Runnable runnable) {
		throw new RuntimeException();
	}

	/**
	 * Returns the amount of free immortal memory still available.
	 *
	 * @return the amount of free immortal memory
	 */
	public static long freeMemory() {
		throw new RuntimeException();
	}

	/**
	 * Returns the total amount of immortal memory.
	 * <p>
	 * Note that the amount of memory required to hold an object of any given type
	 * may be implementation-dependent.
	 *
	 * @return the total amount of immortal memory
	 */
	public static long totalMemory() {
		throw new RuntimeException();
	}

}