/**
 * Copyright (C) 2007 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.ErrorMessage;
import com.google.inject.internal.StackTraceElements;
import com.google.inject.spi.SourceProvider;
import com.google.inject.spi.SourceProviders;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * Creates bindings to methods annotated with {@literal @}
 * {@link com.google.inject.Provides}. Use the scope and binding annotations
 * on the provider method to configure the binding.
 */
public class ProviderMethods {

  /**
   * Returns a module which creates bindings for provider methods from the
   * given object.
   */
  public static Module from(Object providers) {
    return new ProviderMethodsModule(providers);
  }

  static class ProviderMethodsModule extends AbstractModule {

    final Object providers;

    Object source;

    final SourceProvider sourceProvider = new SourceProvider() {
      public Object source() {
        return source;
      }
    };

    ProviderMethodsModule(Object providers) {
      this.providers = providers;
    }

    protected void configure() {
      SourceProviders.withDefault(sourceProvider, new Runnable() {
        public void run() {
          bindProviderMethods(providers.getClass());
        }
      });
    }

    void bindProviderMethods(Class<?> clazz) {
      if (clazz == Object.class) {
        return;
      }

      bindProviderMethods(clazz.getSuperclass());

      for (Method method : clazz.getDeclaredMethods()) {
        if (method.isAnnotationPresent(Provides.class)) {
          bindProviderMethod(method);
        }
      }
    }

    <T> void bindProviderMethod(final Method method) {
      this.source = StackTraceElements.forMember(method);

      method.setAccessible(true);

      Class<? extends Annotation> scopeAnnotation
          = findScopeAnnotation(method.getAnnotations());
      Annotation bindingAnnotation = findBindingAnnotation(
          method.getAnnotations());

      final List<Provider<?>> parameterProviders
          = findParameterProviders(method);

      // Define T as the method's return type.
      @SuppressWarnings("unchecked")
      TypeLiteral<T> returnType 
          = (TypeLiteral<T>) TypeLiteral.get(method.getGenericReturnType());

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

          try {
            // We know this cast is safe becase T is the method's return type.
            @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"})
            T result = (T) method.invoke(providers, parameters);
            return result;
          }
          catch (IllegalAccessException e) {
            throw new AssertionError(e);
          }
          catch (InvocationTargetException e) {
            throw new RuntimeException(e);
          }
        }
      };

      if (scopeAnnotation == null && bindingAnnotation == null) {
        bind(returnType).toProvider(provider);
      } else if (scopeAnnotation == null) {
        bind(returnType).annotatedWith(bindingAnnotation).toProvider(provider);
      } else if (bindingAnnotation == null) {
        bind(returnType).toProvider(provider).in(scopeAnnotation);
      } else {
        bind(returnType)
            .annotatedWith(bindingAnnotation)
            .toProvider(provider)
            .in(scopeAnnotation);
      }
    }

    List<Provider<?>> findParameterProviders(Method method) {
      List<Provider<?>> parameterProviders = new ArrayList<Provider<?>>();

      Type[] parameterTypes = method.getGenericParameterTypes();
      Annotation[][] parameterAnnotations = method.getParameterAnnotations();
      for (int i = 0; i < parameterTypes.length; i++) {
        Annotation bindingAnnotation =
          findBindingAnnotation(parameterAnnotations[i]);
        Key<?> key = bindingAnnotation == null
            ? Key.get(parameterTypes[i])
            : Key.get(parameterTypes[i], bindingAnnotation);
        Provider<?> provider = getProvider(key);
        parameterProviders.add(provider);
      }

      return parameterProviders;
    }

    Class<? extends Annotation> findScopeAnnotation(Annotation[] annotations) {
      Class<? extends Annotation> found = null;

      for (Annotation annotation : annotations) {
        if (annotation.annotationType()
            .isAnnotationPresent(ScopeAnnotation.class)) {
          if (found != null) {
            addError(ErrorMessage.duplicateScopeAnnotations(
                found, annotation.annotationType()).toString());
          } else {
            found = annotation.annotationType();
          }
        }
      }

      return found;
    }

    Annotation findBindingAnnotation(Annotation[] annotations) {
      Annotation found = null;

      for (Annotation annotation : annotations) {
        if (annotation.annotationType()
            .isAnnotationPresent(BindingAnnotation.class)) {
          if (found != null) {
            addError(ErrorMessage.duplicateBindingAnnotations(
                found.annotationType(), annotation.annotationType()).toString());
          } else {
            found = annotation;
          }
        }
      }

      return found;
    }
  }
}
