/**
 * Copyright (C) 2009 Google Inc.
 *
 * Licensed 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 com.google.inject;

import com.google.inject.internal.BytecodeGen;
import static com.google.inject.internal.BytecodeGen.newFastClass;
import com.google.inject.internal.ImmutableList;
import com.google.inject.internal.ImmutableMap;
import com.google.inject.internal.Lists;
import com.google.inject.internal.Maps;
import com.google.inject.spi.InjectionPoint;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.CallbackFilter;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.reflect.FastClass;
import net.sf.cglib.reflect.FastConstructor;
import org.aopalliance.intercept.MethodInterceptor;

/**
 * Builds a construction proxy that can participate in AOP. This class manages applying type and
 * method matchers to come up with the set of intercepted methods.
 *
 * @author jessewilson@google.com (Jesse Wilson)
 */
class ProxyFactory<T> implements ConstructionProxyFactory<T> {

  private static final net.sf.cglib.proxy.MethodInterceptor NO_OP_METHOD_INTERCEPTOR
      = new net.sf.cglib.proxy.MethodInterceptor() {
    public Object intercept(
        Object proxy, Method method, Object[] arguments, MethodProxy methodProxy)
        throws Throwable {
      return methodProxy.invokeSuper(proxy, arguments);
    }
  };

  private final InjectionPoint injectionPoint;
  private final ImmutableMap<Method, List<MethodInterceptor>> interceptors;
  private final Class<T> declaringClass;
  private final List<Method> methods;
  private final Callback[] callbacks;

  /**
   * PUBLIC is default; it's used if all the methods we're intercepting are public. This impacts
   * which classloader we should use for loading the enhanced class
   */
  private BytecodeGen.Visibility visibility = BytecodeGen.Visibility.PUBLIC;

  ProxyFactory(InjectionPoint injectionPoint, Iterable<MethodAspect> methodAspects) {
    this.injectionPoint = injectionPoint;

    @SuppressWarnings("unchecked") // the member of injectionPoint is always a Constructor<T>
        Constructor<T> constructor = (Constructor<T>) injectionPoint.getMember();
    declaringClass = constructor.getDeclaringClass();

    // Find applicable aspects. Bow out if none are applicable to this class.
    List<MethodAspect> applicableAspects = Lists.newArrayList();
    for (MethodAspect methodAspect : methodAspects) {
      if (methodAspect.matches(declaringClass)) {
        applicableAspects.add(methodAspect);
      }
    }

    if (applicableAspects.isEmpty()) {
      interceptors = ImmutableMap.of();
      methods = ImmutableList.of();
      callbacks = null;
      return;
    }

    // Get list of methods from cglib.
    methods = Lists.newArrayList();
    Enhancer.getMethods(declaringClass, null, methods);

    // Create method/interceptor holders and record indices.
    List<MethodInterceptorsPair> methodInterceptorsPairs = Lists.newArrayList();
    for (Method method : methods) {
      methodInterceptorsPairs.add(new MethodInterceptorsPair(method));
    }

    // Iterate over aspects and add interceptors for the methods they apply to
    boolean anyMatched = false;
    for (MethodAspect methodAspect : applicableAspects) {
      for (MethodInterceptorsPair pair : methodInterceptorsPairs) {
        if (methodAspect.matches(pair.method)) {
          visibility = visibility.and(BytecodeGen.Visibility.forMember(pair.method));
          pair.addAll(methodAspect.interceptors());
          anyMatched = true;
        }
      }
    }

    if (!anyMatched) {
      interceptors = ImmutableMap.of();
      callbacks = null;
      return;
    }

    ImmutableMap.Builder<Method, List<MethodInterceptor>> interceptorsMapBuilder = null; // lazy

    callbacks = new Callback[methods.size()];
    for (int i = 0; i < methods.size(); i++) {
      MethodInterceptorsPair pair = methodInterceptorsPairs.get(i);

      if (!pair.hasInterceptors()) {
        callbacks[i] = NO_OP_METHOD_INTERCEPTOR;
        continue;
      }

      if (interceptorsMapBuilder == null) {
        interceptorsMapBuilder = ImmutableMap.builder();
      }

      interceptorsMapBuilder.put(pair.method, ImmutableList.copyOf(pair.interceptors));
      callbacks[i] = new InterceptorStackCallback(pair.method, pair.interceptors);
    }

    interceptors = interceptorsMapBuilder != null
        ? interceptorsMapBuilder.build()
        : ImmutableMap.<Method, List<MethodInterceptor>>of();
  }

  /**
   * Returns the interceptors that apply to the constructed type. When InjectableType.Listeners
   * add additional interceptors, this builder will be thrown out and another created.n
   */
  public ImmutableMap<Method, List<MethodInterceptor>> getInterceptors() {
    return interceptors;
  }

  public ConstructionProxy<T> create() {
    if (interceptors.isEmpty()) {
      return new DefaultConstructionProxyFactory<T>(injectionPoint).create();
    }

    @SuppressWarnings("unchecked")
    Class<? extends Callback>[] callbackTypes = new Class[methods.size()];
    Arrays.fill(callbackTypes, net.sf.cglib.proxy.MethodInterceptor.class);

    // Create the proxied class. We're careful to ensure that all enhancer state is not-specific
    // to this injector. Otherwise, the proxies for each injector will waste PermGen memory
    Enhancer enhancer = BytecodeGen.newEnhancer(declaringClass, visibility);
    enhancer.setCallbackFilter(new IndicesCallbackFilter(declaringClass, methods));
    enhancer.setCallbackTypes(callbackTypes);
    return new ProxyConstructor<T>(enhancer, injectionPoint, callbacks, interceptors);
  }

  private static class MethodInterceptorsPair {
    final Method method;
    List<MethodInterceptor> interceptors; // lazy

    MethodInterceptorsPair(Method method) {
      this.method = method;
    }

    void addAll(List<MethodInterceptor> interceptors) {
      if (this.interceptors == null) {
        this.interceptors = Lists.newArrayList();
      }
      this.interceptors.addAll(interceptors);
    }

    boolean hasInterceptors() {
      return interceptors != null;
    }
  }

  /**
   * A callback filter that maps methods to unique IDs. We define equals and hashCode using the
   * declaring class so that enhanced classes can be shared between injectors.
   */
  private static class IndicesCallbackFilter implements CallbackFilter {
    final Class<?> declaringClass;
    final Map<Method, Integer> indices;

    IndicesCallbackFilter(Class<?> declaringClass, List<Method> methods) {
      this.declaringClass = declaringClass;
      final Map<Method, Integer> indices = Maps.newHashMap();
      for (int i = 0; i < methods.size(); i++) {
        Method method = methods.get(i);
        indices.put(method, i);
      }

      this.indices = indices;
    }

    public int accept(Method method) {
      return indices.get(method);
    }

    @Override public boolean equals(Object o) {
      return o instanceof IndicesCallbackFilter &&
          ((IndicesCallbackFilter) o).declaringClass == declaringClass;
    }

    @Override public int hashCode() {
      return declaringClass.hashCode();
    }
  }

  /**
   * Constructs instances that participate in AOP.
   */
  private static class ProxyConstructor<T> implements ConstructionProxy<T> {
    final Class<?> enhanced;
    final InjectionPoint injectionPoint;
    final Constructor<T> constructor;
    final Callback[] callbacks;

    final FastConstructor fastConstructor;
    final ImmutableMap<Method, List<MethodInterceptor>> methodInterceptors;

    @SuppressWarnings("unchecked") // the constructor promises to construct 'T's
    ProxyConstructor(Enhancer enhancer, InjectionPoint injectionPoint, Callback[] callbacks,
        ImmutableMap<Method, List<MethodInterceptor>> methodInterceptors) {
      this.enhanced = enhancer.createClass(); // this returns a cached class if possible
      this.injectionPoint = injectionPoint;
      this.constructor = (Constructor<T>) injectionPoint.getMember();
      this.callbacks = callbacks;
      this.methodInterceptors = methodInterceptors;

      FastClass fastClass = newFastClass(enhanced, BytecodeGen.Visibility.forMember(constructor));
      this.fastConstructor = fastClass.getConstructor(constructor.getParameterTypes());
    }

    @SuppressWarnings("unchecked") // the constructor promises to produce 'T's
    public T newInstance(Object[] arguments) throws InvocationTargetException {
      Enhancer.registerCallbacks(enhanced, callbacks);
      try {
        return (T) fastConstructor.newInstance(arguments);
      } finally {
        Enhancer.registerCallbacks(enhanced, null);
      }
    }

    public InjectionPoint getInjectionPoint() {
      return injectionPoint;
    }

    public Constructor<T> getConstructor() {
      return constructor;
    }

    public Map<Method, List<MethodInterceptor>> getMethodInterceptors() {
      return methodInterceptors;
    }
  }
}
