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

import static com.google.inject.internal.Annotations.getKey;

import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.inject.ConfigurationException;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
import com.google.inject.internal.BytecodeGen;
import com.google.inject.internal.Errors;
import com.google.inject.internal.ErrorsException;
import com.google.inject.spi.Dependency;
import com.google.inject.spi.HasDependencies;
import com.google.inject.spi.Message;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <strong>Obsolete.</strong> Prefer {@link FactoryModuleBuilder} for its more concise API and
 * additional capability.
 *
 * <p>Provides a factory that combines the caller's arguments with injector-supplied values to
 * construct objects.
 *
 * <h3>Defining a factory</h3>
 * Create an interface whose methods return the constructed type, or any of its supertypes. The
 * method's parameters are the arguments required to build the constructed type.
 * <pre>public interface PaymentFactory {
 *   Payment create(Date startDate, Money amount);
 * }</pre>
 * You can name your factory methods whatever you like, such as <i>create</i>, <i>createPayment</i>
 * or <i>newPayment</i>.
 *
 * <h3>Creating a type that accepts factory parameters</h3>
 * {@code constructedType} is a concrete class with an {@literal @}{@link Inject}-annotated
 * constructor. In addition to injector-supplied parameters, the constructor should have
 * parameters that match each of the factory method's parameters. Each factory-supplied parameter
 * requires an {@literal @}{@link Assisted} annotation. This serves to document that the parameter
 * is not bound by your application's modules.
 * <pre>public class RealPayment implements Payment {
 *   {@literal @}Inject
 *   public RealPayment(
 *      CreditService creditService,
 *      AuthService authService,
 *      <strong>{@literal @}Assisted Date startDate</strong>,
 *      <strong>{@literal @}Assisted Money amount</strong>) {
 *     ...
 *   }
 * }</pre>
 * Any parameter that permits a null value should also be annotated {@code @Nullable}.
 *
 * <h3>Configuring factories</h3>
 * In your {@link com.google.inject.Module module}, bind the factory interface to the returned
 * factory:
 * <pre>bind(PaymentFactory.class).toProvider(
 *     FactoryProvider.newFactory(PaymentFactory.class, RealPayment.class));</pre>
 * As a side-effect of this binding, Guice will inject the factory to initialize it for use. The
 * factory cannot be used until the injector has been initialized.
 *
 * <h3>Using the factory</h3>
 * Inject your factory into your application classes. When you use the factory, your arguments
 * will be combined with values from the injector to construct an instance.
 * <pre>public class PaymentAction {
 *   {@literal @}Inject private PaymentFactory paymentFactory;
 *
 *   public void doPayment(Money amount) {
 *     Payment payment = paymentFactory.create(new Date(), amount);
 *     payment.apply();
 *   }
 * }</pre>
 *
 * <h3>Making parameter types distinct</h3>
 * The types of the factory method's parameters must be distinct. To use multiple parameters of
 * the same type, use a named {@literal @}{@link Assisted} annotation to disambiguate the
 * parameters. The names must be applied to the factory method's parameters:
 *
 * <pre>public interface PaymentFactory {
 *   Payment create(
 *       <strong>{@literal @}Assisted("startDate")</strong> Date startDate,
 *       <strong>{@literal @}Assisted("dueDate")</strong> Date dueDate,
 *       Money amount);
 * } </pre>
 * ...and to the concrete type's constructor parameters:
 * <pre>public class RealPayment implements Payment {
 *   {@literal @}Inject
 *   public RealPayment(
 *      CreditService creditService,
 *      AuthService authService,
 *      <strong>{@literal @}Assisted("startDate")</strong> Date startDate,
 *      <strong>{@literal @}Assisted("dueDate")</strong> Date dueDate,
 *      <strong>{@literal @}Assisted</strong> Money amount) {
 *     ...
 *   }
 * }</pre>
 *
 * <h3>Values are created by Guice</h3>
 * Returned factories use child injectors to create values. The values are eligible for method
 * interception. In addition, {@literal @}{@literal Inject} members will be injected before they are
 * returned.
 *
 * <h3>Backwards compatibility using {@literal @}AssistedInject</h3>
 * Instead of the {@literal @}Inject annotation, you may annotate the constructed classes with
 * {@literal @}{@link AssistedInject}. This triggers a limited backwards-compatability mode.
 *
 * <p>Instead of matching factory method arguments to constructor parameters using their names, the
 * <strong>parameters are matched by their order</strong>. The first factory method argument is
 * used for the first {@literal @}Assisted constructor parameter, etc.. Annotation names have no
 * effect.
 *
 * <p>Returned values are <strong>not created by Guice</strong>. These types are not eligible for
 * method interception. They do receive post-construction member injection.
 *
 * @param <F> The factory interface
 *
 * @author jmourits@google.com (Jerome Mourits)
 * @author jessewilson@google.com (Jesse Wilson)
 * @author dtm@google.com (Daniel Martin)
 * 
 * @deprecated use {@link FactoryModuleBuilder} instead.
 */
@Deprecated
public class FactoryProvider<F> implements Provider<F>, HasDependencies {

  /*
   * This class implements the old @AssistedInject implementation that manually matches constructors
   * to factory methods. The new child injector implementation lives in FactoryProvider2.
   */

  private Injector injector;

  private final TypeLiteral<F> factoryType;
  private final TypeLiteral<?> implementationType;
  private final Map<Method, AssistedConstructor<?>> factoryMethodToConstructor;

  public static <F> Provider<F> newFactory(Class<F> factoryType, Class<?> implementationType){
    return newFactory(TypeLiteral.get(factoryType), TypeLiteral.get(implementationType));
  }

  public static <F> Provider<F> newFactory(
      TypeLiteral<F> factoryType, TypeLiteral<?> implementationType) {
    Map<Method, AssistedConstructor<?>> factoryMethodToConstructor
        = createMethodMapping(factoryType, implementationType);

    if (!factoryMethodToConstructor.isEmpty()) {
      return new FactoryProvider<F>(factoryType, implementationType, factoryMethodToConstructor);
    } else {
      BindingCollector collector = new BindingCollector();

      // Preserving backwards-compatibility:  Map all return types in a factory
      // interface to the passed implementation type.
      Errors errors = new Errors();
      Key<?> implementationKey = Key.get(implementationType);

      try {
        for (Method method : factoryType.getRawType().getMethods()) {
          Key<?> returnType = getKey(factoryType.getReturnType(method), method,
              method.getAnnotations(), errors);
          if (!implementationKey.equals(returnType)) {
            collector.addBinding(returnType, implementationType);
          }
      }
      } catch (ErrorsException e) {
        throw new ConfigurationException(e.getErrors().getMessages());
      }

      return new FactoryProvider2<F>(Key.get(factoryType), collector);
    }
  }

  private FactoryProvider(TypeLiteral<F> factoryType,
      TypeLiteral<?> implementationType,
      Map<Method, AssistedConstructor<?>> factoryMethodToConstructor) {
    this.factoryType = factoryType;
    this.implementationType = implementationType;
    this.factoryMethodToConstructor = factoryMethodToConstructor;
    checkDeclaredExceptionsMatch();
  }

  @Inject
  void setInjectorAndCheckUnboundParametersAreInjectable(Injector injector) {
    this.injector = injector;
    for (AssistedConstructor<?> c : factoryMethodToConstructor.values()) {
      for (Parameter p : c.getAllParameters()) {
        if(!p.isProvidedByFactory() && !paramCanBeInjected(p, injector)) {
          // this is lame - we're not using the proper mechanism to add an
          // error to the injector. Throughout this class we throw exceptions
          // to add errors, which isn't really the best way in Guice
          throw newConfigurationException("Parameter of type '%s' is not injectable or annotated "
                + "with @Assisted for Constructor '%s'", p, c);
        }
      }
    }
  }

  private void checkDeclaredExceptionsMatch() {
    for (Map.Entry<Method, AssistedConstructor<?>> entry : factoryMethodToConstructor.entrySet()) {
      for (Class<?> constructorException : entry.getValue().getDeclaredExceptions()) {
        if (!isConstructorExceptionCompatibleWithFactoryExeception(
            constructorException, entry.getKey().getExceptionTypes())) {
          throw newConfigurationException("Constructor %s declares an exception, but no compatible "
              + "exception is thrown by the factory method %s", entry.getValue(), entry.getKey());
        }
      }
    }
  }

  private boolean isConstructorExceptionCompatibleWithFactoryExeception(
      Class<?> constructorException, Class<?>[] factoryExceptions) {
    for (Class<?> factoryException : factoryExceptions) {
      if (factoryException.isAssignableFrom(constructorException)) {
        return true;
      }
    }
    return false;
  }

  private boolean paramCanBeInjected(Parameter parameter, Injector injector) {
    return parameter.isBound(injector);
  }

  private static Map<Method, AssistedConstructor<?>> createMethodMapping(
      TypeLiteral<?> factoryType, TypeLiteral<?> implementationType) {
    List<AssistedConstructor<?>> constructors = Lists.newArrayList();

    for (Constructor<?> constructor : implementationType.getRawType().getDeclaredConstructors()) {
      if (constructor.isAnnotationPresent(AssistedInject.class)) {
        AssistedConstructor<?> assistedConstructor = AssistedConstructor.create(
            constructor, implementationType.getParameterTypes(constructor));
        constructors.add(assistedConstructor);
      }
    }

    if (constructors.isEmpty()) {
      return ImmutableMap.of();
    }

    Method[] factoryMethods = factoryType.getRawType().getMethods();

    if (constructors.size() != factoryMethods.length) {
      throw newConfigurationException("Constructor mismatch: %s has %s @AssistedInject "
          + "constructors, factory %s has %s creation methods", implementationType,
          constructors.size(), factoryType, factoryMethods.length);
    }

    Map<ParameterListKey, AssistedConstructor<?>> paramsToConstructor = Maps.newHashMap();

    for (AssistedConstructor<?> c : constructors) {
      if (paramsToConstructor.containsKey(c.getAssistedParameters())) {
        throw new RuntimeException("Duplicate constructor, " + c);
      }
      paramsToConstructor.put(c.getAssistedParameters(), c);
    }

    Map<Method, AssistedConstructor<?>> result = Maps.newHashMap();
    for (Method method : factoryMethods) {
      if (!method.getReturnType().isAssignableFrom(implementationType.getRawType())) {
        throw newConfigurationException("Return type of method %s is not assignable from %s",
            method, implementationType);
      }

      List<Type> parameterTypes = Lists.newArrayList();
      for (TypeLiteral<?> parameterType : factoryType.getParameterTypes(method)) {
        parameterTypes.add(parameterType.getType());
      }
      ParameterListKey methodParams = new ParameterListKey(parameterTypes);

      if (!paramsToConstructor.containsKey(methodParams)) {
        throw newConfigurationException("%s has no @AssistInject constructor that takes the "
            + "@Assisted parameters %s in that order. @AssistInject constructors are %s",
            implementationType, methodParams, paramsToConstructor.values());
      }

      method.getParameterAnnotations();
      for (Annotation[] parameterAnnotations : method.getParameterAnnotations()) {
        for (Annotation parameterAnnotation : parameterAnnotations) {
          if (parameterAnnotation.annotationType() == Assisted.class) {
            throw newConfigurationException("Factory method %s has an @Assisted parameter, which "
                + "is incompatible with the deprecated @AssistedInject annotation. Please replace "
                + "@AssistedInject with @Inject on the %s constructor.",
                method, implementationType);
          }
        }
      }

      AssistedConstructor<?> matchingConstructor = paramsToConstructor.remove(methodParams);

      result.put(method, matchingConstructor);
    }
    return result;
  }

  public Set<Dependency<?>> getDependencies() {
    List<Dependency<?>> dependencies = Lists.newArrayList();
    for (AssistedConstructor<?> constructor : factoryMethodToConstructor.values()) {
      for (Parameter parameter : constructor.getAllParameters()) {
        if (!parameter.isProvidedByFactory()) {
          dependencies.add(Dependency.get(parameter.getPrimaryBindingKey()));
        }
      }
    }
    return ImmutableSet.copyOf(dependencies);
  }

  public F get() {
    InvocationHandler invocationHandler = new InvocationHandler() {
      public Object invoke(Object proxy, Method method, Object[] creationArgs) throws Throwable {
        // pass methods from Object.class to the proxy
        if (method.getDeclaringClass().equals(Object.class)) {
          if ("equals".equals(method.getName())) {
            return proxy == creationArgs[0];
          } else if ("hashCode".equals(method.getName())) {
            return System.identityHashCode(proxy);
          } else {
            return method.invoke(this, creationArgs);
          }
        }

        AssistedConstructor<?> constructor = factoryMethodToConstructor.get(method);
        Object[] constructorArgs = gatherArgsForConstructor(constructor, creationArgs);
        Object objectToReturn = constructor.newInstance(constructorArgs);
        injector.injectMembers(objectToReturn);
        return objectToReturn;
      }

      public Object[] gatherArgsForConstructor(
          AssistedConstructor<?> constructor,
          Object[] factoryArgs) {
        int numParams = constructor.getAllParameters().size();
        int argPosition = 0;
        Object[] result = new Object[numParams];

        for (int i = 0; i < numParams; i++) {
          Parameter parameter = constructor.getAllParameters().get(i);
          if (parameter.isProvidedByFactory()) {
            result[i] = factoryArgs[argPosition];
            argPosition++;
          } else {
            result[i] = parameter.getValue(injector);
          }
        }
        return result;
      }
    };

    @SuppressWarnings("unchecked") // we imprecisely treat the class literal of T as a Class<T>
    Class<F> factoryRawType = (Class<F>) (Class<?>) factoryType.getRawType();
    return factoryRawType.cast(Proxy.newProxyInstance(BytecodeGen.getClassLoader(factoryRawType),
        new Class[] { factoryRawType }, invocationHandler));
  }

  @Override
  public int hashCode() {
    return Objects.hashCode(factoryType, implementationType);
  }

  @Override
  public boolean equals(Object obj) {
    if (!(obj instanceof FactoryProvider)) {
      return false;
    }
    FactoryProvider<?> other = (FactoryProvider<?>) obj;
    return factoryType.equals(other.factoryType)
        && implementationType.equals(other.implementationType);
  }

  private static ConfigurationException newConfigurationException(String format, Object... args) {
    return new ConfigurationException(ImmutableSet.of(new Message(Errors.format(format, args))));
  }
}
