/*
 * 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.assertTrue;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import org.apache.aries.proxy.FinalModifierException;
import org.apache.aries.proxy.InvocationListener;
import org.apache.aries.proxy.UnableToProxyException;
import org.apache.aries.proxy.impl.SingleInstanceDispatcher;
import org.apache.aries.proxy.impl.gen.ProxySubclassGenerator;
import org.apache.aries.proxy.impl.gen.ProxySubclassMethodHashSet;
import org.apache.aries.proxy.impl.interfaces.InterfaceProxyGenerator;
import org.apache.aries.proxy.weaving.WovenProxy;
import org.apache.aries.unittest.mocks.MethodCall;
import org.apache.aries.unittest.mocks.Skeleton;
import org.apache.aries.util.ClassLoaderProxy;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.osgi.framework.Bundle;
import org.osgi.framework.wiring.BundleWiring;

/**
 * This class uses the {@link ProxySubclassGenerator} to test
 */
public class WovenProxyPlusSubclassGeneratorTest extends WovenProxyGeneratorTest
{
  private static final Class<?> FINAL_METHOD_CLASS = ProxyTestClassFinalMethod.class;
  private static final Class<?> FINAL_CLASS = ProxyTestClassFinal.class;
  private static final Class<?> GENERIC_CLASS = ProxyTestClassGeneric.class;
  private static final Class<?> COVARIANT_CLASS = ProxyTestClassCovariantOverride.class;
  private static ProxySubclassMethodHashSet<String> expectedMethods = new ProxySubclassMethodHashSet<String>(
      12);
  private Callable<Object> testCallable = null;
  
  private static Bundle testBundle;
  private static BundleWiring testBundleWiring;

  @BeforeClass
  public static void createTestBundle() {
	  testBundle = (Bundle) Skeleton.newMock(new Class<?>[] {Bundle.class, ClassLoaderProxy.class});
	  testBundleWiring = (BundleWiring) Skeleton.newMock(BundleWiring.class);

	    Skeleton.getSkeleton(testBundle).setReturnValue(new MethodCall(
	        ClassLoaderProxy.class, "getClassLoader"), weavingLoader);
	    Skeleton.getSkeleton(testBundle).setReturnValue(new MethodCall(
	        ClassLoaderProxy.class, "adapt", BundleWiring.class), testBundleWiring);
  }

  //Avoid running four weaving tests that don't apply to us
  public void testUnweavableSuperWithNoNoargsAllTheWay() {}
  public void testUnweavableSuperWithFinalMethod() {}
  public void testUnweavableSuperWithDefaultMethodInWrongPackage() {}
  public void testInnerWithNoParentNoArgs() {}
  
  
  @Test(expected=NoSuchFieldException.class)
  public void testGeneratedSVUIDisSynthetic() throws Exception {
    super.testGeneratedSVUIDisSynthetic();
  }
  
  
//
//  /**
//   * Test that the methods found declared on the generated proxy subclass are
//   * the ones that we expect.
//   */
//  @Test
//  public void testExpectedMethods() throws Exception
//  {
//    Class<?> superclass = getTestClass();
//
//    do {
//      Method[] declaredMethods = superclass.getDeclaredMethods();
//      List<Method> listOfDeclaredMethods = new ArrayList<Method>();
//      for (Method m : declaredMethods) {
//    	
//        if(m.getName().equals("clone") || m.getName().equals("finalize"))
//        	continue;
//    	
//        int i = m.getModifiers();
//        if (Modifier.isPrivate(i) || Modifier.isFinal(i)) {
//          // private or final don't get added
//        } else if (!(Modifier.isPublic(i) || Modifier.isPrivate(i) || Modifier.isProtected(i))) {
//          // the method is default visibility, check the package
//          if (m.getDeclaringClass().getPackage().equals(getTestClass().getPackage())) {
//            // default vis with same package gets added
//            listOfDeclaredMethods.add(m);
//          }
//        } else {
//          listOfDeclaredMethods.add(m);
//        }
//      }
//
//      declaredMethods = listOfDeclaredMethods.toArray(new Method[] {});
//      ProxySubclassMethodHashSet<String> foundMethods = new ProxySubclassMethodHashSet<String>(
//          declaredMethods.length);
//      foundMethods.addMethodArray(declaredMethods);
//      // as we are using a set we shouldn't get duplicates
//      expectedMethods.addAll(foundMethods);
//      superclass = superclass.getSuperclass();
//    } while (superclass != null);
//
//    
//    
//    Method[] subclassMethods = getProxyClass(getTestClass()).getDeclaredMethods();
//    List<Method> listOfDeclaredMethods = new ArrayList<Method>();
//    for (Method m : subclassMethods) {
//      if(m.getName().startsWith(WovenProxy.class.getName().replace('.', '_')))
//        continue;
//      
//      listOfDeclaredMethods.add(m);
//    }
//    subclassMethods = listOfDeclaredMethods.toArray(new Method[] {});
//    
//    ProxySubclassMethodHashSet<String> generatedMethods = new ProxySubclassMethodHashSet<String>(
//    		subclassMethods.length);
//        generatedMethods.addMethodArray(subclassMethods);
//        
//    // check that all the methods we have generated were expected
//    for (String gen : generatedMethods) {
//      assertTrue("Unexpected method: " + gen, expectedMethods.contains(gen));
//    }
//    // check that all the expected methods were generated
//    for (String exp : expectedMethods) {
//      assertTrue("Method was not generated: " + exp, generatedMethods.contains(exp));
//    }
//    // check the sets were the same
//    assertEquals("Sets were not the same", expectedMethods, generatedMethods);
//
//  }
//
  
  
  /**
   * Test a covariant override method
   */
  @Test
  public void testCovariant() throws Exception
  {
    Class<?> proxy = getProxyClass(ProxyTestClassCovariantOverride.class);
    
    Method m = getDeclaredMethod(ProxyTestClassCovariantOverride.class, "getCovariant", new Class[] {});
    Object returned = m.invoke(getProxyInstance(proxy));
    assertTrue("Object was of wrong type: " + returned.getClass().getSimpleName(),
        proxy.getSuperclass().isInstance(returned));
  }
  
  /**
   * Test a method marked final
   */
  @Test
  public void testFinalMethod() throws Exception
  {
    try {
      InterfaceProxyGenerator.getProxyInstance(null, FINAL_METHOD_CLASS, Collections.EMPTY_SET, 
          new Callable<Object>() {
        public Object call() throws Exception {
          return null;
        }} , null).getClass();
    } catch (RuntimeException re) {
      FinalModifierException e = (FinalModifierException) re.getCause();
      assertFalse("Should have found final method not final class", e.isFinalClass());
    }
  }

  /**
   * Test a class marked final
   */
  @Test
  public void testFinalClass() throws Exception
  {
    try {
      InterfaceProxyGenerator.getProxyInstance(null, FINAL_CLASS, Collections.EMPTY_SET, 
          new Callable() {
        public Object call() throws Exception {
          return null;
        }} , null).getClass();
    } catch (FinalModifierException e) {
      assertTrue("Should have found final class", e.isFinalClass());
    }
  }


  
  @Test
  public void testAddingInterfacesToClass() throws Exception {
    Object proxy = InterfaceProxyGenerator.getProxyInstance(testBundle, super.getProxyClass(getTestClass()), Arrays.asList(Map.class, Iterable.class), new Callable<Object>() {

        int calls = 0;
        private Map<String, String> map = new HashMap<String, String>();
        
        {
          map.put("key", "value");
        }

        public Object call() throws Exception {
          switch(++calls) {
            case 1 :
              return WovenProxyPlusSubclassGeneratorTest.super.getProxyInstance(weavingLoader.loadClass(getTestClass().getName()));
            case 2 :
              return map;
            default :
              return map.values();
          }
		}
    	
    }, null);
    
    Method m = weavingLoader.loadClass(ProxyTestClassGeneral.class.getName()).getDeclaredMethod("testReturnInt");
    m.setAccessible(true);
    assertEquals(17, m.invoke(proxy));
    assertEquals("value", ((Map<String, String>)proxy).put("key", "value2"));
    Iterator<?> it = ((Iterable<?>)proxy).iterator();
    assertEquals("value2", it.next());
    assertFalse(it.hasNext());
	  
  }
  
  
  
  
  @Override
  protected Method getDeclaredMethod(Class<?> testClass, String name,
		Class<?>... classes) {

	  Class<?> proxy = getProxyClass(testClass);
	  
	  while(proxy != null) {
	    try {
			return proxy.getDeclaredMethod(name, classes);
		} catch (Exception e) {
			proxy = proxy.getSuperclass();
		}
	  }
	  return null;
  }

  @Override
  protected Object getProxyInstance(Class<?> proxyClass) {
	 
    if(proxyClass == ProxyTestClassChildOfAbstract.class) {
    	return super.getProxyInstance(super.getProxyClass(proxyClass));
    }
	  
    try {
      Constructor<?> con = proxyClass.getDeclaredConstructor(Callable.class, InvocationListener.class);
      con.setAccessible(true);
      return con.newInstance((testCallable == null) ? new SingleInstanceDispatcher(super.getProxyInstance(proxyClass.getSuperclass())) : testCallable, null);
    } catch (Exception e) {
      return null;
    }
  }

  @Override
  protected Class<?> getProxyClass(Class<?> clazz) {
    try {
      return InterfaceProxyGenerator.getProxyInstance(testBundle, super.getProxyClass(clazz), Collections.EMPTY_SET, 
          new Callable<Object>() {
        public Object call() throws Exception {
          return null;
        }} , null).getClass();
    } catch (UnableToProxyException e) {
      return null;
    } catch (RuntimeException re) {
      if(re.getCause() instanceof UnableToProxyException)
        return null;
      else
        throw re;
    }
  }

  @Override
  protected Object getProxyInstance(Class<?> proxyClass,
      InvocationListener listener) {
    WovenProxy proxy = (WovenProxy) getProxyInstance(proxyClass);
    proxy = proxy.org_apache_aries_proxy_weaving_WovenProxy_createNewProxyInstance(
        new SingleInstanceDispatcher(proxy), listener);
    return proxy;
  }
}