/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.aries.blueprint.proxy;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;

import org.apache.aries.blueprint.proxy.ProxyTestClassInnerClasses.ProxyTestClassInner;
import org.apache.aries.blueprint.proxy.ProxyTestClassInnerClasses.ProxyTestClassStaticInner;
import org.apache.aries.proxy.InvocationListener;
import org.apache.aries.proxy.impl.SingleInstanceDispatcher;
import org.junit.Test;

public abstract class AbstractProxyTest {

  protected static class TestListener implements InvocationListener {
  
    boolean preInvoke = false;
    boolean postInvoke = false;
    boolean postInvokeExceptionalReturn = false;
    private Method m;
    private Object token;
    private Throwable e;
    
    public Object preInvoke(Object proxy, Method m, Object[] args)
        throws Throwable {
      preInvoke = true;
      token = new Object();
      this.m = m;
      return token;
    }
  
    public void postInvoke(Object token, Object proxy, Method m,
        Object returnValue) throws Throwable {
      postInvoke = this.token == token && this.m == m;
    }
  
    public void postInvokeExceptionalReturn(Object token, Object proxy,
        Method m, Throwable exception) throws Throwable {
      postInvokeExceptionalReturn = this.token == token && this.m == m;
      e = exception;
    }
    
    public void clear() {
      preInvoke = false;
      postInvoke = false;
      postInvokeExceptionalReturn = false;
      token = null;
      m = null;
      e = null;
    }
    
    public Method getLastMethod() {
      return m;
    }
    
    public Throwable getLastThrowable() {
      return e;
    }
  }

  protected abstract Object getProxyInstance(Class<?> proxyClass);
  protected abstract Object getProxyInstance(Class<?> proxyClass, InvocationListener listener);
  protected abstract Class<?> getProxyClass(Class<?> clazz);
  protected abstract Object setDelegate(Object proxy, Callable<Object> dispatcher);
  
  protected Class<?> getTestClass() {
	  return ProxyTestClassGeneral.class;
  }
  
  protected Method getDeclaredMethod(Class<?> testClass, String name,
		Class<?>... classes) throws Exception {
	return getProxyClass(testClass).getDeclaredMethod(name, classes);
  }
  
/**
   * This test uses the ProxySubclassGenerator to generate and load a subclass
   * of the specified getTestClass().
   * 
   * Once the subclass is generated we check that it wasn't null. We check
   * that the InvocationHandler constructor doesn't return a null object
   * either
   * 
   * Test method for
   * {@link org.apache.aries.proxy.impl.ProxySubclassGenerator#generateAndLoadSubclass()}
   * .
   */
  @Test
  public void testGenerateAndLoadProxy() throws Exception
  {
    assertNotNull("Generated proxy subclass was null", getProxyClass(getTestClass()));
    assertNotNull("Generated proxy subclass instance was null", getProxyInstance(getProxyClass(getTestClass())));
  }
  /**
   * Test a basic method invocation on the proxy subclass
   */
  @Test
  public void testMethodInvocation() throws Exception {
    Method m = getDeclaredMethod(getTestClass(), "testMethod", String.class,
        int.class, Object.class);
    String x = "x";
    String returned = (String) m.invoke(getProxyInstance(getProxyClass(getTestClass())), x, 1, new Object());
    assertEquals("Object returned from invocation was not correct.", x, returned);
  }
  
  /**
   * Test different argument types on a method invocation
   */
  @Test
  public void testMethodArgs() throws Exception
  {
    Method m = getDeclaredMethod(getTestClass(), "testArgs", double.class,
        short.class, long.class, char.class, byte.class, boolean.class);
    Character xc = Character.valueOf('x');
    String x = xc.toString();
    String returned = (String) m.invoke(getProxyInstance(getProxyClass(getTestClass())), Double.MAX_VALUE, Short.MIN_VALUE, Long.MAX_VALUE, xc
        .charValue(), Byte.MIN_VALUE, false);
    assertEquals("Object returned from invocation was not correct.", x, returned);
  }
  
  /**
   * Test a method that returns void
   */
  @Test
  public void testReturnVoid() throws Exception
  {
    Method m = getDeclaredMethod(getTestClass(), "testReturnVoid");
    //for these weaving tests we are loading the woven test classes on a different classloader
    //to this class so we need to set the method accessible
    m.setAccessible(true);
    m.invoke(getProxyInstance(getProxyClass(getTestClass())));
  }

  /**
   * Test a method that returns an int
   */
  @Test
  public void testReturnInt() throws Exception
  {
    Method m = getDeclaredMethod(getTestClass(), "testReturnInt");
    //for these weaving tests we are loading the woven test classes on a different classloader
    //to this class so we need to set the method accessible
    m.setAccessible(true);
    Integer returned = (Integer) m.invoke(getProxyInstance(getProxyClass(getTestClass())));
    assertEquals("Expected object was not returned from invocation", Integer.valueOf(17), returned);
  }

  /**
   * Test a method that returns an Integer
   */
  @Test
  public void testReturnInteger() throws Exception
  {
    Method m = getDeclaredMethod(getTestClass(), "testReturnInteger");
    Integer returned = (Integer) m.invoke(getProxyInstance(getProxyClass(getTestClass())));
    assertEquals("Expected object was not returned from invocation", Integer.valueOf(1), returned);
  }

  /**
   * Test a public method declared higher up the superclass hierarchy
   */
  @Test
  public void testPublicHierarchyMethod() throws Exception
  {
    Method m = null;
    try {
      m = getDeclaredMethod(getTestClass(), "bMethod");
    } catch (NoSuchMethodException nsme) {
      m = getProxyClass(getTestClass()).getSuperclass().getDeclaredMethod("bMethod");
    }
    m.invoke(getProxyInstance(getProxyClass(getTestClass())));
  }

  /**
   * Test a protected method declared higher up the superclass hierarchy
   */
  @Test
  public void testProtectedHierarchyMethod() throws Exception
  {
    Method m = null;
    try {
      m = getDeclaredMethod(getTestClass(), "bProMethod");
    } catch (NoSuchMethodException nsme) {
      m = getProxyClass(getTestClass()).getSuperclass().getDeclaredMethod("bProMethod");
    }
    //for these weaving tests we are loading the woven test classes on a different classloader
    //to this class so we need to set the method accessible
    m.setAccessible(true);
    m.invoke(getProxyInstance(getProxyClass(getTestClass())));
  }
  
  /**
   * Test a default method declared higher up the superclass hierarchy
   */
  @Test
  public void testDefaultHierarchyMethod() throws Exception
  {
    Method m = null;
    try {
      m = getDeclaredMethod(getTestClass(), "bDefMethod");
    } catch (NoSuchMethodException nsme) {
      m = getProxyClass(getTestClass()).getSuperclass().getDeclaredMethod("bDefMethod", new Class[] {});
    }
    //for these weaving tests we are loading the woven test classes on a different classloader
    //to this class so we need to set the method accessible
    m.setAccessible(true);
    m.invoke(getProxyInstance(getProxyClass(getTestClass())));
  }

  /**
   * Test a covariant override method
   */
  @Test
  public void testCovariant() throws Exception
  {
    Class<?> proxy = getProxyClass(ProxyTestClassCovariantOverride.class);
    
    Method m = getDeclaredMethod(ProxyTestClassCovariantOverride.class, "getCovariant");
    Object returned = m.invoke(getProxyInstance(proxy));
    assertTrue("Object was of wrong type: " + returned.getClass().getSimpleName(),
        proxy.isInstance(returned));
  }

  /**
   * Test a method with generics
   */
  @Test
  public void testGenerics() throws Exception
  {
    Class<?> proxy = getProxyClass(ProxyTestClassGeneric.class);
    
    Object o = getProxyInstance(proxy);
    Method m = getDeclaredMethod(ProxyTestClassGeneric.class, "setSomething", String.class);
    m.invoke(o, "aString");
    
    if(getClass() == WovenProxyGeneratorTest.class)
    	m = getDeclaredMethod(ProxyTestClassGeneric.class.getSuperclass(), "getSomething");
    else 
        m = getDeclaredMethod(ProxyTestClassGeneric.class, "getSomething");

    Object returned = m.invoke(o);
    assertTrue("Object was of wrong type", String.class.isInstance(returned));
    assertEquals("String had wrong value", "aString", returned);
  }
  
  /**
   * Test that we don't generate classes twice
   */
  @Test
  public void testRetrieveClass() throws Exception
  {
    Class<?> retrieved = getProxyClass(getTestClass());
    assertNotNull("The new class was null", retrieved);
    assertEquals("The same class was not returned", retrieved, getProxyClass(getTestClass()));

  }
  
  @Test
  public void testEquals() throws Exception {
    Object p1 = getProxyInstance(getProxyClass(getTestClass()));
    Object p2 = getProxyInstance(getProxyClass(getTestClass()));
    
    assertFalse("Should not be equal", p1.equals(p2));
    
    Object p3 = getP3();
    
    p1 = setDelegate(p1, new SingleInstanceDispatcher(p3));
    p2 = setDelegate(p2, new SingleInstanceDispatcher(p3));
    
    assertTrue("Should be equal", p1.equals(p2));
    
    Object p4 = getProxyInstance(getProxyClass(getTestClass()));
    Object p5 = getProxyInstance(getProxyClass(getTestClass()));
    
    p4 = setDelegate(p4, new SingleInstanceDispatcher(p1));
    p5 = setDelegate(p5, new SingleInstanceDispatcher(p2));
    
    assertTrue("Should be equal", p4.equals(p5));
  }
  
  protected abstract Object getP3() throws Exception;
  
  @Test
  public void testInterception() throws Throwable {
    
    TestListener tl = new TestListener();
    Object obj = getProxyInstance(getProxyClass(getTestClass()), tl);
    
    assertCalled(tl, false, false, false);
    
    Method m = getDeclaredMethod(getTestClass(), "testReturnInteger", new Class[] {});
    m.invoke(obj);
    
    assertCalled(tl, true, true, false);
    
    tl.clear();
    assertCalled(tl, false, false, false);
    
    m = getDeclaredMethod(getTestClass(), "testException", new Class[] {});
    try {
      m.invoke(obj);
      fail("Should throw an exception");
    } catch (InvocationTargetException re) {
      if(!!!re.getTargetException().getClass().equals(RuntimeException.class))
        throw re.getTargetException();
      assertCalled(tl, true, false, true);
    }
    
    tl.clear();
    assertCalled(tl, false, false, false);
    
    m = getDeclaredMethod(getTestClass(), "testInternallyCaughtException", new Class[] {});
    try {
      m.invoke(obj);
    } finally {
      assertCalled(tl, true, true, false);
    }
  }
  
  protected void assertCalled(TestListener listener, boolean pre, boolean post, boolean ex) {
    assertEquals(pre, listener.preInvoke);
    assertEquals(post, listener.postInvoke);
    assertEquals(ex, listener.postInvokeExceptionalReturn);
  }
  @Test
  public void testStaticInner() throws Exception {
    assertNotNull(getProxyInstance(getProxyClass(ProxyTestClassStaticInner.class)));
  }
  @Test
  public void testInner() throws Exception {
    //An inner class has no no-args (the parent gets added as an arg) so we can't
    //get an instance
    assertNotNull(getProxyClass(ProxyTestClassInner.class));
  }
  
  /**
   * Test an abstract class
   */
  @Test
  public void testAbstractClass() throws Exception
  {
    Object ptca = getProxyInstance(getProxyClass(ProxyTestClassAbstract.class));
    ptca = setDelegate(ptca, new Callable<Object>() {

      public Object call() throws Exception {
        //We have to use a proxy instance here because we need it to be a subclass
        //of the one from the weaving loader in the weaving test...
        return getProxyInstance(ProxyTestClassChildOfAbstract.class);
      }
    });
    
    Method m = ptca.getClass().getDeclaredMethod("getMessage");
    assertEquals("Working", m.invoke(ptca));
  }
}
