package gov.va.med.fw.service.config;

// Java classes

// Library classes
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;

// Framework classes
import gov.va.med.fw.util.Reflector;
import gov.va.med.fw.util.AbstractContextAwareTestCase;

// ESR classes

public class ReflectorTest extends AbstractContextAwareTestCase {

	private Log logger = LogFactory.getLog( getClass() );
	
	public ReflectorTest(String arg0) {
		super(arg0);
	}

	public void testDeclaredMethod() throws Exception {
		Class ret = null;
		
		/*Class ret = (Class) Reflector.invoke( this, "doIt", new Object[]{ "123" } );
		logger.info( "Return value type " + ret.getName() );*/
		
		ret = (Class) Reflector.invoke( this, "doIt", new Object[]{ new A() } );
		logger.info( "Return value type " + ret.getName() );

		ret = (Class) Reflector.invoke( this, "doIt", new Object[]{ new B() } );
		logger.info( "Return value type " + ret.getName() );
		
		ret = (Class) Reflector.invoke( this, "doIt", new Object[]{ new C() } );
		logger.info( "Return value type " + ret.getName() );

		
		Class[] retArray = (Class[]) Reflector.invoke( this, "doIt", new Object[]{ new C(), new C() } );
		logger.info( "Return value type " + retArray[0].getName() );				
		logger.info( "Return value type " + retArray[1].getName() );

		retArray = (Class[]) Reflector.invoke( this, "doIt", new Object[]{ new B(), new B() } );
		logger.info( "Return value type " + retArray[0].getName() );				
		logger.info( "Return value type " + retArray[1].getName() );
		
		ret = (Class) Reflector.invoke( this, "doIt", new Object[]{ new D() } );
		logger.info( "Return value type " + ret.getName() );

		ret = (Class) Reflector.invoke( this, "doIt", new Object[]{ new E() } );
		logger.info( "Return value type " + ret.getName() );
		
	}
	
	/*public Class doIt( Object input ) {
		Class argType = Object.class;
		logger.info( "Received formal arg1: " + argType.getName() );
		return argType;
	}*/
	public Class doIt( A input ) {
		Class argType = A.class;
		logger.info( "Received formal arg1: " + argType.getName() );
		return argType;
	}
	public Class doIt( B input ) {
		Class argType = B.class;
		logger.info( "Received formal arg1: " + argType.getName() );
		return argType;
	}

	public Class doIt( X input ) {
		Class argType = X.class;
		logger.info( "Received formal arg1: " + argType.getName() );
		return argType;
	}
	
	public Class doIt( Y input ) {
		Class argType = Y.class;
		logger.info( "Received formal arg1: " + argType.getName() );
		return argType;
	}
	
	public Class[] doIt( B input1, B input2 ) {
		Class[] argType = new Class[] {B.class, B.class};
		logger.info( "Received formal arg1: " + argType[0].getName() );
		logger.info( "Received formal arg2: " + argType[1].getName() );
		return argType;		
	}

	public Class[] doIt( A input1, A input2 ) {
		Class[] argType = new Class[] {A.class, A.class};
		logger.info( "Received formal arg1: " + argType[0].getName() );
		logger.info( "Received formal arg2: " + argType[1].getName() );
		return argType;		
	}
	
	public class A {
		public A() {}
		public String toString() {
			return getClass().getName();
		}
	}
	
	public class B extends A {
		public B() {}
		public String toString() {
			return getClass().getName();
		}
	}
	
	public class C extends B {
		public C() {}
		public String toString() {
			return getClass().getName();
		}
	}	
	
	public class D implements X {
		public D() {}
		public String toString() {
			return getClass().getName();
		}
	}

	
	public class E implements Y {
		public E() {}
		public String toString() {
			return getClass().getName();
		}
	}
	
	
	public interface X {}
	public interface Y extends X {}
	public interface Z {}
}
