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

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.inject.multibindings.Multibinder.checkConfiguration;
import static com.google.inject.util.Types.newParameterizedType;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Binder;
import com.google.inject.Binding;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
import com.google.inject.binder.LinkedBindingBuilder;
import com.google.inject.spi.BindingTargetVisitor;
import com.google.inject.spi.Dependency;
import com.google.inject.spi.Element;
import com.google.inject.spi.ProviderInstanceBinding;
import com.google.inject.spi.ProviderLookup;
import com.google.inject.spi.ProviderWithDependencies;
import com.google.inject.spi.ProviderWithExtensionVisitor;
import com.google.inject.spi.Toolable;
import com.google.inject.util.Types;

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.reflect.Type;
import java.util.Set;

import javax.inject.Qualifier;


/**
 * An API to bind optional values, optionally with a default value.
 * OptionalBinder fulfills two roles: <ol>
 * <li>It allows a framework to define an injection point that may or
 *     may not be bound by users.
 * <li>It allows a framework to supply a default value that can be changed
 *     by users.
 * </ol>
 * 
 * <p>When an OptionalBinder is added, it will always supply the bindings:
 * {@code Optional<T>} and {@code Optional<Provider<T>>}.  If
 * {@link #setBinding} or {@link #setDefault} are called, it will also
 * bind {@code T}.
 * 
 * <p>{@code setDefault} is intended for use by frameworks that need a default
 * value.  User code can call {@code setBinding} to override the default.
 * <b>Warning: Even if setBinding is called, the default binding
 * will still exist in the object graph.  If it is a singleton, it will be
 * instantiated in {@code Stage.PRODUCTION}.</b>
 * 
 * <p>If setDefault or setBinding are linked to Providers, the Provider may return
 * {@code null}.  If it does, the Optional bindings will be absent.  Binding
 * setBinding to a Provider that returns null will not cause OptionalBinder
 * to fall back to the setDefault binding.
 * 
 * <p>If neither setDefault nor setBinding are called, it will try to link to a
 * user-supplied binding of the same type.  If no binding exists, the optionals
 * will be absent.  Otherwise, if a user-supplied binding of that type exists,
 * or if setBinding or setDefault are called, the optionals will return present
 * if they are bound to a non-null value.
 *
 * <p>Values are resolved at injection time. If a value is bound to a
 * provider, that provider's get method will be called each time the optional
 * is injected (unless the binding is also scoped, or an optional of provider is
 * injected).
 * 
 * <p>Annotations are used to create different optionals of the same key/value
 * type. Each distinct annotation gets its own independent binding.
 *  
 * <pre><code>
 * public class FrameworkModule extends AbstractModule {
 *   protected void configure() {
 *     OptionalBinder.newOptionalBinder(binder(), Renamer.class);
 *   }
 * }</code></pre>
 *
 * <p>With this module, an {@link Optional}{@code <Renamer>} can now be
 * injected.  With no other bindings, the optional will be absent.
 * Users can specify bindings in one of two ways:
 * 
 * <p>Option 1:
 * <pre><code>
 * public class UserRenamerModule extends AbstractModule {
 *   protected void configure() {
 *     bind(Renamer.class).to(ReplacingRenamer.class);
 *   }
 * }</code></pre>
 * 
 * <p>or Option 2:
 * <pre><code>
 * public class UserRenamerModule extends AbstractModule {
 *   protected void configure() {
 *     OptionalBinder.newOptionalBinder(binder(), Renamer.class)
 *         .setBinding().to(ReplacingRenamer.class);
 *   }
 * }</code></pre>
 * With both options, the {@code Optional<Renamer>} will be present and supply the
 * ReplacingRenamer. 
 * 
 * <p>Default values can be supplied using:
 * <pre><code>
 * public class FrameworkModule extends AbstractModule {
 *   protected void configure() {
 *     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
 *         .setDefault().to(DEFAULT_LOOKUP_URL);
 *   }
 * }</code></pre>
 * With the above module, code can inject an {@code @LookupUrl String} and it
 * will supply the DEFAULT_LOOKUP_URL.  A user can change this value by binding
 * <pre><code>
 * public class UserLookupModule extends AbstractModule {
 *   protected void configure() {
 *     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
 *         .setBinding().to(CUSTOM_LOOKUP_URL);
 *   }
 * }</code></pre>
 * ... which will override the default value.
 * 
 * <p>If one module uses setDefault the only way to override the default is to use setBinding.
 * It is an error for a user to specify the binding without using OptionalBinder if
 * setDefault or setBinding are called.  For example, 
 * <pre><code>
 * public class FrameworkModule extends AbstractModule {
 *   protected void configure() {
 *     OptionalBinder.newOptionalBinder(binder(), Key.get(String.class, LookupUrl.class))
 *         .setDefault().to(DEFAULT_LOOKUP_URL);
 *   }
 * }
 * public class UserLookupModule extends AbstractModule {
 *   protected void configure() {
 *     bind(Key.get(String.class, LookupUrl.class)).to(CUSTOM_LOOKUP_URL);
 *   } 
 * }</code></pre>
 * ... would generate an error, because both the framework and the user are trying to bind
 * {@code @LookupUrl String}. 
 *
 * @author sameb@google.com (Sam Berlin)
 */
public abstract class OptionalBinder<T> {
  private OptionalBinder() {}

  public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, Class<T> type) {
    return newOptionalBinder(binder, Key.get(type));
  }
  
  public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, TypeLiteral<T> type) {
    return newOptionalBinder(binder, Key.get(type));
  }
  
  public static <T> OptionalBinder<T> newOptionalBinder(Binder binder, Key<T> type) {
    binder = binder.skipSources(OptionalBinder.class, RealOptionalBinder.class);
    RealOptionalBinder<T> optionalBinder = new RealOptionalBinder<T>(binder, type);
    binder.install(optionalBinder);
    return optionalBinder;
  }

  @SuppressWarnings("unchecked")
  static <T> TypeLiteral<Optional<T>> optionalOf(
      TypeLiteral<T> type) {
    return (TypeLiteral<Optional<T>>) TypeLiteral.get(
        Types.newParameterizedType(Optional.class,  type.getType()));
  }

  @SuppressWarnings("unchecked")
  static <T> TypeLiteral<Optional<javax.inject.Provider<T>>> optionalOfJavaxProvider(
      TypeLiteral<T> type) {
    return (TypeLiteral<Optional<javax.inject.Provider<T>>>) TypeLiteral.get(
        Types.newParameterizedType(Optional.class,
            newParameterizedType(javax.inject.Provider.class, type.getType())));
  }

  @SuppressWarnings("unchecked")
  static <T> TypeLiteral<Optional<Provider<T>>> optionalOfProvider(TypeLiteral<T> type) {
    return (TypeLiteral<Optional<Provider<T>>>) TypeLiteral.get(Types.newParameterizedType(
        Optional.class, newParameterizedType(Provider.class, type.getType())));
  }
  
  @SuppressWarnings("unchecked")
  static <T> Key<Provider<T>> providerOf(Key<T> key) {
    Type providerT = Types.providerOf(key.getTypeLiteral().getType());
    return (Key<Provider<T>>) key.ofType(providerT);
  }

  /**
   * Returns a binding builder used to set the default value that will be injected.
   * The binding set by this method will be ignored if {@link #setBinding} is called.
   * 
   * <p>It is an error to call this method without also calling one of the {@code to}
   * methods on the returned binding builder. 
   */
  public abstract LinkedBindingBuilder<T> setDefault();


  /**
   * Returns a binding builder used to set the actual value that will be injected.
   * This overrides any binding set by {@link #setDefault}.
   * 
   * <p>It is an error to call this method without also calling one of the {@code to}
   * methods on the returned binding builder. 
   */
  public abstract LinkedBindingBuilder<T> setBinding();
  
  enum Source { DEFAULT, ACTUAL }
  
  @Retention(RUNTIME)
  @Qualifier
  @interface Default {
    String value();
  }

  @Retention(RUNTIME)
  @Qualifier
  @interface Actual {
    String value();
  }

  /**
   * The actual OptionalBinder plays several roles.  It implements Module to hide that
   * fact from the public API, and installs the various bindings that are exposed to the user.
   */
  static final class RealOptionalBinder<T> extends OptionalBinder<T> implements Module {
    private final Key<T> typeKey;
    private final Key<Optional<T>> optionalKey;
    private final Key<Optional<javax.inject.Provider<T>>> optionalJavaxProviderKey;
    private final Key<Optional<Provider<T>>> optionalProviderKey;
    private final Provider<Optional<Provider<T>>> optionalProviderT;
    private final Key<T> defaultKey;
    private final Key<T> actualKey;

    /** the target injector's binder. non-null until initialization, null afterwards */
    private Binder binder;
    /** the default binding, for the SPI. */
    private Binding<T> defaultBinding;
    /** the actual binding, for the SPI */
    private Binding<T> actualBinding;
    
    /** the dependencies -- initialized with defaults & overridden when tooled. */
    private Set<Dependency<?>> dependencies;
    /** the dependencies -- initialized with defaults & overridden when tooled. */
    private Set<Dependency<?>> providerDependencies;

    private RealOptionalBinder(Binder binder, Key<T> typeKey) {
      this.binder = binder;
      this.typeKey = checkNotNull(typeKey);
      TypeLiteral<T> literal = typeKey.getTypeLiteral();
      this.optionalKey = typeKey.ofType(optionalOf(literal));
      this.optionalJavaxProviderKey = typeKey.ofType(optionalOfJavaxProvider(literal));
      this.optionalProviderKey = typeKey.ofType(optionalOfProvider(literal));
      this.optionalProviderT = binder.getProvider(optionalProviderKey);
      String name = RealElement.nameOf(typeKey);
      this.defaultKey = Key.get(typeKey.getTypeLiteral(), new DefaultImpl(name));
      this.actualKey = Key.get(typeKey.getTypeLiteral(), new ActualImpl(name));
      // Until the injector initializes us, we don't know what our dependencies are,
      // so initialize to the whole Injector (like Multibinder, and MapBinder indirectly).
      this.dependencies = ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class)));
      this.providerDependencies =
          ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(Injector.class)));
    }
    
    /**
     * Adds a binding for T. Multiple calls to this are safe, and will be collapsed as duplicate
     * bindings.
     */
    private void addDirectTypeBinding(Binder binder) {
      binder.bind(typeKey).toProvider(new RealOptionalBinderProviderWithDependencies<T>(typeKey) {
        @Override public T get() {
          Optional<Provider<T>> optional = optionalProviderT.get();
          if (optional.isPresent()) {
            return optional.get().get();
          }
          // Let Guice handle blowing up if the injection point doesn't have @Nullable
          // (If it does have @Nullable, that's fine.  This would only happen if
          //  setBinding/setDefault themselves were bound to 'null').
          return null; 
        }

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

    @Override public LinkedBindingBuilder<T> setDefault() {
      checkConfiguration(!isInitialized(), "already initialized");      
      addDirectTypeBinding(binder);
      return binder.bind(defaultKey);
    }

    @Override public LinkedBindingBuilder<T> setBinding() {
      checkConfiguration(!isInitialized(), "already initialized");      
      addDirectTypeBinding(binder);
      return binder.bind(actualKey);
    }

    @Override public void configure(Binder binder) {
      checkConfiguration(!isInitialized(), "OptionalBinder was already initialized");

      binder.bind(optionalProviderKey).toProvider(
          new RealOptionalBinderProviderWithDependencies<Optional<Provider<T>>>(typeKey) {
        private Optional<Provider<T>> optional;

        @Toolable @Inject void initialize(Injector injector) {
          RealOptionalBinder.this.binder = null;
          actualBinding = injector.getExistingBinding(actualKey);
          defaultBinding = injector.getExistingBinding(defaultKey);
          Binding<T> userBinding = injector.getExistingBinding(typeKey);
          Binding<T> binding = null;
          if (actualBinding != null) {
            // TODO(sameb): Consider exposing an option that will allow
            // ACTUAL to fallback to DEFAULT if ACTUAL's provider returns null.
            // Right now, an ACTUAL binding can convert from present -> absent
            // if it's bound to a provider that returns null.
            binding = actualBinding;
          } else if (defaultBinding != null) {
            binding = defaultBinding;
          } else if (userBinding != null) {
            // If neither the actual or default is set, then we fallback
            // to the value bound to the type itself and consider that the
            // "actual binding" for the SPI.
            binding = userBinding;
            actualBinding = userBinding;
          }
          
          if (binding != null) {
            optional = Optional.of(binding.getProvider());
            RealOptionalBinder.this.dependencies =
                ImmutableSet.<Dependency<?>>of(Dependency.get(binding.getKey()));
            RealOptionalBinder.this.providerDependencies = 
                ImmutableSet.<Dependency<?>>of(Dependency.get(providerOf(binding.getKey())));
          } else {            
            optional = Optional.absent();
            RealOptionalBinder.this.dependencies = ImmutableSet.of();
            RealOptionalBinder.this.providerDependencies = ImmutableSet.of();
          }
        }
        
        @Override public Optional<Provider<T>> get() {
          return optional;
        }

        @Override public Set<Dependency<?>> getDependencies() {
          return providerDependencies;
        }
      });
      
      // Optional is immutable, so it's safe to expose Optional<Provider<T>> as
      // Optional<javax.inject.Provider<T>> (since Guice provider implements javax Provider).
      @SuppressWarnings({"unchecked", "cast"})
      Key massagedOptionalProviderKey = (Key) optionalProviderKey;
      binder.bind(optionalJavaxProviderKey).to(massagedOptionalProviderKey);

      binder.bind(optionalKey).toProvider(new RealOptionalKeyProvider());
    }

    private class RealOptionalKeyProvider
        extends RealOptionalBinderProviderWithDependencies<Optional<T>>
        implements ProviderWithExtensionVisitor<Optional<T>>,
            OptionalBinderBinding<Optional<T>>,
            Provider<Optional<T>> {
      RealOptionalKeyProvider() {
        super(typeKey);
      }
      
      @Override public Optional<T> get() {
        Optional<Provider<T>> optional = optionalProviderT.get();
        if (optional.isPresent()) {
          return Optional.fromNullable(optional.get().get());
        } else {
          return Optional.absent();
        }
      }

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

      @SuppressWarnings("unchecked")
      @Override
      public <B, R> R acceptExtensionVisitor(BindingTargetVisitor<B, R> visitor,
          ProviderInstanceBinding<? extends B> binding) {
        if (visitor instanceof MultibindingsTargetVisitor) {
          return ((MultibindingsTargetVisitor<Optional<T>, R>) visitor).visit(this);
        } else {
          return visitor.visit(binding);
        }
      }

      @Override public Key<Optional<T>> getKey() {
        return optionalKey;
      }
      
      @Override public Binding<?> getActualBinding() {
        if (isInitialized()) {
          return actualBinding;
        } else {
          throw new UnsupportedOperationException(
              "getActualBinding() not supported from Elements.getElements, requires an Injector.");
        }
      }
      
      @Override public Binding<?> getDefaultBinding() {
        if (isInitialized()) {
          return defaultBinding;
        } else {
          throw new UnsupportedOperationException(
              "getDefaultBinding() not supported from Elements.getElements, requires an Injector.");
        }
      }

      @Override public boolean containsElement(Element element) {
        Key<?> elementKey;
        if (element instanceof Binding) {
          elementKey = ((Binding<?>) element).getKey();
        } else if (element instanceof ProviderLookup) {
          elementKey = ((ProviderLookup<?>) element).getKey();
        } else {
          return false; // cannot match;
        }

        return elementKey.equals(optionalKey)
            || elementKey.equals(optionalProviderKey)
            || elementKey.equals(optionalJavaxProviderKey)
            || elementKey.equals(defaultKey)
            || elementKey.equals(actualKey)
            || matchesTypeKey(element, elementKey);
      }
    }
    
    /** Returns true if the key & element indicate they were bound by this OptionalBinder. */
    private boolean matchesTypeKey(Element element, Key<?> elementKey) {
      // Just doing .equals(typeKey) isn't enough, because the user can bind that themselves.
      return elementKey.equals(typeKey)
          && element instanceof ProviderInstanceBinding
          && (((ProviderInstanceBinding) element)
              .getUserSuppliedProvider() instanceof RealOptionalBinderProviderWithDependencies);
    }

    private boolean isInitialized() {
      return binder == null;
    }

    @Override public boolean equals(Object o) {
      return o instanceof RealOptionalBinder
          && ((RealOptionalBinder<?>) o).typeKey.equals(typeKey);
    }

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

    /**
     * A base class for ProviderWithDependencies that need equality based on a specific object.
     */
    private abstract static class RealOptionalBinderProviderWithDependencies<T> implements
        ProviderWithDependencies<T> {
      private final Object equality;

      public RealOptionalBinderProviderWithDependencies(Object equality) {
        this.equality = equality;
      }

      @Override public boolean equals(Object obj) {
        return this.getClass() == obj.getClass()
            && equality.equals(((RealOptionalBinderProviderWithDependencies<?>) obj).equality);
      }

      @Override public int hashCode() {
        return equality.hashCode();
      }
    }
  }
  
  static class DefaultImpl extends BaseAnnotation implements Default {
    public DefaultImpl(String value) {
      super(Default.class, value);
    }
  }
  
  static class ActualImpl extends BaseAnnotation implements Actual {
    public ActualImpl(String value) {
      super(Actual.class, value);
    }
  }
  
  abstract static class BaseAnnotation implements Serializable, Annotation {

    private final String value;
    private final Class<? extends Annotation> clazz;

    BaseAnnotation(Class<? extends Annotation> clazz, String value) {
      this.clazz = checkNotNull(clazz, "clazz");
      this.value = checkNotNull(value, "value");
    }

    public String value() {
      return this.value;
    }

    @Override public int hashCode() {
      // This is specified in java.lang.Annotation.
      return (127 * "value".hashCode()) ^ value.hashCode();
    }

    @Override public boolean equals(Object o) {
      // We check against each annotation type instead of BaseAnnotation
      // so that we can compare against generated annotation implementations. 
      if (o instanceof Actual && clazz == Actual.class) {
        Actual other = (Actual) o;
        return value.equals(other.value());
      } else if (o instanceof Default && clazz == Default.class) {
        Default other = (Default) o;
        return value.equals(other.value());
      }
      return false;
    }

    @Override public String toString() {
      return "@" + clazz.getName() + (value.isEmpty() ? "" : "(value=" + value + ")");
    }

    @Override public Class<? extends Annotation> annotationType() {
      return clazz;
    }

    private static final long serialVersionUID = 0;
  }
}
