/**
 * Copyright (C) 2008 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.internal;

import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Binder;
import com.google.inject.Exposed;
import com.google.inject.Key;
import com.google.inject.PrivateBinder;
import com.google.inject.Provider;
import com.google.inject.Provides;
import com.google.inject.internal.BytecodeGen.Visibility;
import com.google.inject.internal.util.StackTraceElements;
import com.google.inject.spi.BindingTargetVisitor;
import com.google.inject.spi.Dependency;
import com.google.inject.spi.HasDependencies;
import com.google.inject.spi.ProviderInstanceBinding;
import com.google.inject.spi.ProviderWithExtensionVisitor;
import com.google.inject.spi.ProvidesMethodBinding;
import com.google.inject.spi.ProvidesMethodTargetVisitor;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Set;

/**
 * A provider that invokes a method and returns its result.
 *
 * @author jessewilson@google.com (Jesse Wilson)
 */
public abstract class ProviderMethod<T> implements ProviderWithExtensionVisitor<T>, HasDependencies,
    ProvidesMethodBinding<T> {

  /**
   * Creates a {@link ProviderMethod}.
   *
   * <p>Unless {@code skipFastClassGeneration} is set, this will use
   * {@link net.sf.cglib.reflect.FastClass} to invoke the actual method, since it is significantly
   * faster. However, this will fail if the method is {@code private} or {@code protected}, since
   * fastclass is subject to java access policies.
   */
  static <T> ProviderMethod<T> create(Key<T> key, Method method, Object instance,
      ImmutableSet<Dependency<?>> dependencies, List<Provider<?>> parameterProviders,
      Class<? extends Annotation> scopeAnnotation, boolean skipFastClassGeneration,
      Annotation annotation) {
    int modifiers = method.getModifiers();
    /*if[AOP]*/
    if (!skipFastClassGeneration && !Modifier.isPrivate(modifiers)
        && !Modifier.isProtected(modifiers)) {
      try {
        // We use an index instead of FastMethod to save a stack frame.
        return new FastClassProviderMethod<T>(key,
            method,
            instance,
            dependencies,
            parameterProviders,
            scopeAnnotation,
            annotation);
      } catch (net.sf.cglib.core.CodeGenerationException e) {/* fall-through */}
    }
    /*end[AOP]*/

    if (!Modifier.isPublic(modifiers) ||
        !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
      method.setAccessible(true);
    }

    return new ReflectionProviderMethod<T>(key,
        method,
        instance,
        dependencies,
        parameterProviders,
        scopeAnnotation,
        annotation);
  }

  protected final Object instance;
  protected final Method method;

  private final Key<T> key;
  private final Class<? extends Annotation> scopeAnnotation;
  private final ImmutableSet<Dependency<?>> dependencies;
  private final List<Provider<?>> parameterProviders;
  private final boolean exposed;
  private final Annotation annotation;

  /**
   * @param method the method to invoke. It's return type must be the same type as {@code key}.
   */
  private ProviderMethod(Key<T> key, Method method, Object instance,
      ImmutableSet<Dependency<?>> dependencies, List<Provider<?>> parameterProviders,
      Class<? extends Annotation> scopeAnnotation, Annotation annotation) {
    this.key = key;
    this.scopeAnnotation = scopeAnnotation;
    this.instance = instance;
    this.dependencies = dependencies;
    this.method = method;
    this.parameterProviders = parameterProviders;
    this.exposed = method.isAnnotationPresent(Exposed.class);
    this.annotation = annotation;
  }

  @Override
  public Key<T> getKey() {
    return key;
  }

  @Override
  public Method getMethod() {
    return method;
  }

  // exposed for GIN
  public Object getInstance() {
    return instance;
  }
  
  @Override
  public Object getEnclosingInstance() {
    return instance;
  }
  
  @Override
  public Annotation getAnnotation() {
    return annotation;
  }

  public void configure(Binder binder) {
    binder = binder.withSource(method);

    if (scopeAnnotation != null) {
      binder.bind(key).toProvider(this).in(scopeAnnotation);
    } else {
      binder.bind(key).toProvider(this);
    }

    if (exposed) {
      // the cast is safe 'cause the only binder we have implements PrivateBinder. If there's a
      // misplaced @Exposed, calling this will add an error to the binder's error queue
      ((PrivateBinder) binder).expose(key);
    }
  }

  @Override
  public T get() {
    Object[] parameters = new Object[parameterProviders.size()];
    for (int i = 0; i < parameters.length; i++) {
      parameters[i] = parameterProviders.get(i).get();
    }

    try {
      @SuppressWarnings({ "unchecked", "UnnecessaryLocalVariable" })
      T result = (T) doProvision(parameters);
      return result;
    } catch (IllegalAccessException e) {
      throw new AssertionError(e);
    } catch (InvocationTargetException e) {
      throw Exceptions.rethrowCause(e);
    }
  }

  /** Extension point for our subclasses to implement the provisioning strategy. */
  abstract Object doProvision(Object[] parameters)
      throws IllegalAccessException, InvocationTargetException;

  @Override
  public Set<Dependency<?>> getDependencies() {
    return dependencies;
  }
  
  @Override
  @SuppressWarnings("unchecked")
  public <B, V> V acceptExtensionVisitor(BindingTargetVisitor<B, V> visitor,
      ProviderInstanceBinding<? extends B> binding) {
    if (visitor instanceof ProvidesMethodTargetVisitor) {
      return ((ProvidesMethodTargetVisitor<T, V>)visitor).visit(this);
    }
    return visitor.visit(binding);
  }

  @Override public String toString() {
    String annotationString = annotation.toString();
    // Show @Provides w/o the com.google.inject prefix.
    if (annotation.annotationType() == Provides.class) {
      annotationString = "@Provides";
    } else if (annotationString.endsWith("()")) {
      // Remove the common "()" suffix if there are no values.
      annotationString = annotationString.substring(0, annotationString.length() - 2);
    }
    return annotationString + " " + StackTraceElements.forMember(method);
  }
  
  @Override
  public boolean equals(Object obj) {
    if (obj instanceof ProviderMethod) {
      ProviderMethod<?> o = (ProviderMethod<?>) obj;
      return method.equals(o.method)
         && instance.equals(o.instance)
         && annotation.equals(o.annotation);
    } else {
      return false;
    }
  }
  
  @Override
  public int hashCode() {
    // Avoid calling hashCode on 'instance', which is a user-object
    // that might not be expecting it.
    // (We need to call equals, so we do.  But we can avoid hashCode.)
    return Objects.hashCode(method, annotation);
  }

  /*if[AOP]*/
  /**
   * A {@link ProviderMethod} implementation that uses {@link net.sf.cglib.reflect.FastClass#invoke}
   * to invoke the provider method.
   */
  private static final class FastClassProviderMethod<T> extends ProviderMethod<T> {
    final net.sf.cglib.reflect.FastClass fastClass;
    final int methodIndex;

    FastClassProviderMethod(Key<T> key,
        Method method,
        Object instance,
        ImmutableSet<Dependency<?>> dependencies,
        List<Provider<?>> parameterProviders,
        Class<? extends Annotation> scopeAnnotation,
        Annotation annotation) {
      super(key,
          method,
          instance,
          dependencies,
          parameterProviders,
          scopeAnnotation,
          annotation);
      // We need to generate a FastClass for the method's class, not the object's class.
      this.fastClass =
          BytecodeGen.newFastClass(method.getDeclaringClass(), Visibility.forMember(method));
      // Use the Signature overload of getIndex because it properly uses return types to identify
      // particular methods.  This is normally irrelevant, except in the case of covariant overrides
      // which java implements with a compiler generated bridge method to implement the override.
      this.methodIndex = fastClass.getIndex(
          new net.sf.cglib.core.Signature(
              method.getName(), org.objectweb.asm.Type.getMethodDescriptor(method)));
      Preconditions.checkArgument(this.methodIndex >= 0, 
          "Could not find method %s in fast class for class %s", 
          method, 
          method.getDeclaringClass());
    }

    @Override public Object doProvision(Object[] parameters)
        throws IllegalAccessException, InvocationTargetException {
      return fastClass.invoke(methodIndex, instance, parameters);
    }
  }
  /*end[AOP]*/

  /**
   * A {@link ProviderMethod} implementation that invokes the method using normal java reflection. 
   */
  private static final class ReflectionProviderMethod<T> extends ProviderMethod<T> {
    ReflectionProviderMethod(Key<T> key,
        Method method,
        Object instance,
        ImmutableSet<Dependency<?>> dependencies,
        List<Provider<?>> parameterProviders,
        Class<? extends Annotation> scopeAnnotation,
        Annotation annotation) {
      super(key,
          method,
          instance,
          dependencies,
          parameterProviders,
          scopeAnnotation,
          annotation);
    }

    @Override Object doProvision(Object[] parameters) throws IllegalAccessException,
        InvocationTargetException {
      return method.invoke(instance, parameters);
    }
  }
}
