/**
 * 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.throwingproviders;

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.TypeLiteral;
import com.google.inject.binder.ScopedBindingBuilder;
import com.google.inject.internal.util.StackTraceElements;
import com.google.inject.spi.Dependency;
import com.google.inject.spi.HasDependencies;
import com.google.inject.throwingproviders.ThrowingProviderBinder.SecondaryBinder;

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

/**
 * A provider that invokes a method and returns its result.
 *
 * @author sameb@google.com (Sam Berlin)
 */
class CheckedProviderMethod<T> implements CheckedProvider<T>, HasDependencies {
  private final Key<T> key;
  private final Class<? extends Annotation> scopeAnnotation;
  private final Object instance;
  private final Method method;
  private final ImmutableSet<Dependency<?>> dependencies;
  private final List<Provider<?>> parameterProviders;
  private final boolean exposed;
  private final Class<? extends CheckedProvider> checkedProvider;
  private final List<TypeLiteral<?>> exceptionTypes;

  CheckedProviderMethod(
      Key<T> key,
      Method method,
      Object instance,
      ImmutableSet<Dependency<?>> dependencies,
      List<Provider<?>> parameterProviders,
      Class<? extends Annotation> scopeAnnotation,
      Class<? extends CheckedProvider> checkedProvider,
      List<TypeLiteral<?>> exceptionTypes) {
    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.checkedProvider = checkedProvider;
    this.exceptionTypes = exceptionTypes;

    method.setAccessible(true);
  }

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

    SecondaryBinder<?, ?> sbinder = 
      ThrowingProviderBinder.create(binder)
        .bind(checkedProvider, key.getTypeLiteral());
    if(key.getAnnotation() != null) {
      sbinder = sbinder.annotatedWith(key.getAnnotation());
    } else if(key.getAnnotationType() != null) {
      sbinder = sbinder.annotatedWith(key.getAnnotationType());
    } 
    ScopedBindingBuilder sbbuilder = sbinder.toProviderMethod(this);
    if(scopeAnnotation != null) {
      sbbuilder.in(scopeAnnotation);
    }

    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(sbinder.getKey());
    }
    
    CheckedProvideUtils.validateExceptions(
        binder, exceptionTypes, sbinder.getExceptionTypes(), checkedProvider);
  }

  public T get() throws Exception {
    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(instance, parameters);
      return result;
    } catch (IllegalAccessException e) {
      throw new AssertionError(e);
    } catch (InvocationTargetException e) {
      Throwable t = e.getCause();
      if(t instanceof Exception) {
        throw (Exception)t;
      } else if(t instanceof Error) {
        throw (Error)t;
      } else {
        throw new IllegalStateException(t);
      }
    }
  }

  public Set<Dependency<?>> getDependencies() {
    return dependencies;
  }

  @Override public String toString() {
    return "@CheckedProvides " + StackTraceElements.forMember(method).toString();
  }
}
