/*
 * Java
 *
 * 2015-2022 ESR - Not subject to Copyright.
 *
 * This document has been released and published by E-S-R consortium, a non-profit entity.
 * To learn more about E-S-R consortium, please visit http://www.e-s-r.net/.
 * The matter contained in this document is not subject to copyright; you are free to use it for any purpose, for more information see E-S-R consortium policies.
 */
package ej.kf;

import ej.annotation.Nullable;

/**
 * The superclass of proxy classes.
 * A proxy class is a class that directly extends this class and directly implements a shared interface.
 * Each method of the implemented interface must be defined according to the following pattern:
 * <pre>
 * public class MyProxy extends Proxy&lt;MySharedInterface&gt; implements MySharedInterface{
 * 	public void foo(){
 * 		try{
 * 			invoke();
 * 		}
 * 		catch(Throwable e){
 * 			// return or throw default case (deny of service)
 * 		}
 * 	}
 * </pre>
 * A {@link Proxy} instance has a link to a reference owned by another {@link Feature}.
 * The reference may be automatically removed by the garbage collector.
 * @param <T> the type managed by this {@link Proxy}
 */
public class Proxy<T>{

	/**
	 * The default constructor.
	 */
	public Proxy(){
		throw new RuntimeException();
	}

	/**
	 * This method has for effect to invoke the same method on the reference. Each argument of the current method is converted and passed to the underlying method.
	 * @throws Throwable any kind of exceptions must be catched by the caller
	 */
	protected final native void invoke() throws Throwable;

	/**
	 * This method has for effect to invoke the same method on the reference. Each argument of the current method is converted and passed to the underlying method.
	 * @return the boolean result of the call of the target method
	 * @throws Throwable any kind of exceptions must be catched by the caller
	 */
	protected final native boolean invokeBoolean() throws Throwable;

	/**
	 * This method has for effect to invoke the same method on the reference. Each argument of the current method is converted and passed to the underlying method.
	 * @return the byte result of the call of the target method
	 * @throws Throwable any kind of exceptions must be catched by the caller
	 */
	protected final native byte invokeByte() throws Throwable;

	/**
	 * This method has for effect to invoke the same method on the reference. Each argument of the current method is converted and passed to the underlying method.
	 * @return the char result of the call of the target method
	 * @throws Throwable any kind of exceptions must be catched by the caller
	 */
	protected final native char invokeChar() throws Throwable;

	/**
	 * This method has for effect to invoke the same method on the reference. Each argument of the current method is converted and passed to the underlying method.
	 * @return the short result of the call of the target method
	 * @throws Throwable any kind of exceptions must be catched by the caller
	 */
	protected final native short invokeShort() throws Throwable;

	/**
	 * This method has for effect to invoke the same method on the reference. Each argument of the current method is converted and passed to the underlying method.
	 * @return the int result of the call of the target method
	 * @throws Throwable any kind of exceptions must be catched by the caller
	 */
	protected final native int invokeInt() throws Throwable;

	/**
	 * This method has for effect to invoke the same method on the reference. Each argument of the current method is converted and passed to the underlying method.
	 * @return the long result of the call of the target method
	 * @throws Throwable any kind of exceptions must be catched by the caller
	 */
	protected final native long invokeLong() throws Throwable;

	/**
	 * This method has for effect to invoke the same method on the reference. Each argument of the current method is converted and passed to the underlying method.
	 * @return the float result of the call of the target method
	 * @throws Throwable any kind of exceptions must be catched by the caller
	 */
	protected final native float invokeFloat() throws Throwable;

	/**
	 * This method has for effect to invoke the same method on the reference. Each argument of the current method is converted and passed to the underlying method.
	 * @return the double result of the call of the target method
	 * @throws Throwable any kind of exceptions must be catched by the caller
	 */
	protected final native double invokeDouble() throws Throwable;

	/**
	 * This method has for effect to invoke the same method on the reference. Each argument of the current method is converted and passed to the underlying method.
	 * @return the {@link Object} result of the call of the target method
	 * @throws Throwable any kind of exceptions must be catched by the caller
	 */
	protected final native Object invokeRef() throws Throwable;

	/**
	 * Returns the reference managed by this {@link Proxy}.
	 * @return the reference or <code>null</code> if the reference has been reclaimed.
	 */
	@Nullable
	public T getReference() {
		throw new RuntimeException();
	}
}
