/*
 * 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.proxy.impl.interfaces;

import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.WeakHashMap;
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.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
import org.osgi.framework.Bundle;
import org.osgi.framework.wiring.BundleWiring;

/**
 * This class is used to aggregate several interfaces into a real class which implements all of them
 * It also allows you specify a superclass that the class should implement - this will add delegating
 * method overrides for any abstract methods in the hierarchy, but not override any non-abstract methods.
 * To be safely used as a supertype the superclass should be a WovenProxy.
 */
public final class InterfaceProxyGenerator extends ClassVisitor implements Opcodes {

  public InterfaceProxyGenerator()
  {
    super(Opcodes.ASM5);
    
  }

  private static final Map<BundleWiring, WeakReference<ProxyClassLoader>> cache =
            new WeakHashMap<BundleWiring, WeakReference<ProxyClassLoader>>(128);
  
  /**
   * Generate a new proxy instance implementing the supplied interfaces and using the supplied
   * dispatcher and listener
   * @param client the bundle that is trying to generate this proxy (can be null)
   * @param superclass The superclass to use (or null for Object)
   * @param ifaces The set of interfaces to implement (may be empty if superclass is non null)
   * @param dispatcher
   * @param listener
   * @return
   * @throws UnableToProxyException
   */
  public static Object getProxyInstance(Bundle client, Class<?> superclass,
      Collection<Class<?>> ifaces, Callable<Object> dispatcher, InvocationListener listener) throws UnableToProxyException{
    
    if(superclass != null && (superclass.getModifiers() & Modifier.FINAL) != 0)
      throw new FinalModifierException(superclass);
    
    ProxyClassLoader pcl = null;
    
    SortedSet<Class<?>> interfaces = createSet(ifaces);
    
    synchronized (cache) {
      BundleWiring wiring = client == null ? null : (BundleWiring)client.adapt(BundleWiring.class);
      WeakReference<ProxyClassLoader> ref = cache.get(wiring);
      
      if(ref != null)
        pcl = ref.get();
      
      if (pcl != null && pcl.isInvalid(interfaces)) {
          pcl = null;
          cache.remove(wiring);
      }
      
      if(pcl == null) {
        pcl = new ProxyClassLoader(client);
        cache.put(wiring, new WeakReference<ProxyClassLoader>(pcl));
      }
    }

    Class<?> c = pcl.createProxyClass(superclass, interfaces);

    try {
      Constructor<?> con = c.getDeclaredConstructor(Callable.class, InvocationListener.class);
      con.setAccessible(true);
      return con.newInstance(dispatcher, listener);
    } catch (Exception e) {
      throw new UnableToProxyException(ifaces.iterator().next(), e);
    }
  }

  /**
   * Get the set of interfaces we need to process. This will return a HashSet 
   * that includes includes the supplied collection and any super-interfaces of 
   * those classes 
   * @param ifaces
   * @return
   */
  private static SortedSet<Class<?>> createSet(Collection<Class<?>> ifaces) {
    SortedSet<Class<?>> classes = new TreeSet<Class<?>>(new Comparator<Class<?>>() {
      public int compare(Class<?> object1, Class<?> object2) {
        if (object1.getName().equals(object2.getName())) {
          return 0;
        } else if (object1.isAssignableFrom(object2)) {
          // first class is parent of second, it occurs earlier in type hierarchy
          return -1;
        } else if (object2.isAssignableFrom(object1)) {
          // second class is subclass of first one, it occurs later in hierarchy
          return 1;
        }
        // types have separate inheritance trees, so it doesn't mater which one is first or second,
        // however we can't mark them as equal cause one of them will be removed
        return 1;
      }
    });
    for(Class<?> c : ifaces) {
      //If we already have a class contained then we have already covered its hierarchy
      if(classes.add(c))
        classes.addAll(createSet(Arrays.asList(c.getInterfaces())));
    }
    return classes;
  }
}