package org.etsi.extfunc.core;



import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.etsi.common.plugins.IXfPlugin;
import org.etsi.ttcn.tri.TriFunctionId;
import org.etsi.ttcn.tri.TriParameter;
import org.etsi.ttcn.tri.TriParameterList;

public abstract class ExternalFunction implements IXfPlugin, InvocationHandler {

	@Override
	public void initPlugin() {
		XfFactory.getInstance().registerXf(this.getPluginName(), this.getClass());
	}

	public abstract void unpack(TriFunctionId functionId, TriParameterList parameterList, TriParameter returnValue);
	
	public Object getProxy(Class<?> iface) {
				
		Class<?>[] xf_ifaces = this.getClass().getInterfaces();
    	Class<?>[] ifaces = new Class[xf_ifaces.length + 1];
    	for(int i=0; i < xf_ifaces.length; i++) {
    		ifaces[i] = xf_ifaces[i];
    	}
    	ifaces[ifaces.length -1] = iface;
    	
    	Object instance = Proxy.newProxyInstance(
			this.getClass().getClassLoader(),
			ifaces,
			this
		);

    	return instance;
	}
	
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    	System.err.println("Calling: " + method.getName());
    	Class<?>[] params = null;
    	if(args != null) {
    		params = new Class<?>[args.length];
        	for(int i=0; i < args.length; i++) {
        		params[i] = args[i].getClass();
        	}
    	}
        Method m = this.getClass().getMethod(method.getName(), params);
        return m.invoke(this, args);
	}

}
