/**
 * 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.inject.Binder;
import com.google.inject.Binding;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.spi.ConstructorBinding;
import com.google.inject.spi.ConvertedConstantBinding;
import com.google.inject.spi.ExposedBinding;
import com.google.inject.spi.InjectionPoint;
import com.google.inject.spi.InstanceBinding;
import com.google.inject.spi.LinkedKeyBinding;
import com.google.inject.spi.PrivateElements;
import com.google.inject.spi.ProviderBinding;
import com.google.inject.spi.ProviderInstanceBinding;
import com.google.inject.spi.ProviderKeyBinding;
import com.google.inject.spi.UntargettedBinding;

import java.util.Set;

/**
 * Handles {@link Binder#bind} and {@link Binder#bindConstant} elements.
 *
 * @author crazybob@google.com (Bob Lee)
 * @author jessewilson@google.com (Jesse Wilson)
 */
final class BindingProcessor extends AbstractBindingProcessor {

  private final Initializer initializer;

  BindingProcessor(Errors errors, Initializer initializer, ProcessedBindingData bindingData) {
    super(errors, bindingData);
    this.initializer = initializer;
  }

  @Override public <T> Boolean visit(Binding<T> command) {
    Class<?> rawType = command.getKey().getTypeLiteral().getRawType();
    if (Void.class.equals(rawType)) {
      if (command instanceof ProviderInstanceBinding
          && ((ProviderInstanceBinding) command).getUserSuppliedProvider()
              instanceof ProviderMethod) {
        errors.voidProviderMethod();
      } else {
        errors.missingConstantValues();
      }
      return true;
    }
    
    if (rawType == Provider.class) {
      errors.bindingToProvider();
      return true;
    }
    
    return command.acceptTargetVisitor(new Processor<T, Boolean>((BindingImpl<T>)command) {
      @Override
      public Boolean visit(ConstructorBinding<? extends T> binding) {
        prepareBinding();
        try {
          ConstructorBindingImpl<T> onInjector = ConstructorBindingImpl.create(injector, key, 
              binding.getConstructor(), source, scoping, errors, false, false);
          scheduleInitialization(onInjector);
          putBinding(onInjector);
        } catch (ErrorsException e) {
          errors.merge(e.getErrors());
          putBinding(invalidBinding(injector, key, source));
        }
        return true;
      }

      @Override
      public Boolean visit(InstanceBinding<? extends T> binding) {
        prepareBinding();
        Set<InjectionPoint> injectionPoints = binding.getInjectionPoints();
        T instance = binding.getInstance();
        @SuppressWarnings("unchecked") // safe to cast to binding<T> because
                                       // the processor was constructed w/ it
        Initializable<T> ref = initializer.requestInjection(
            injector, instance, (Binding<T>) binding, source, injectionPoints);
        ConstantFactory<? extends T> factory = new ConstantFactory<T>(ref);
        InternalFactory<? extends T> scopedFactory
            = Scoping.scope(key, injector, factory, source, scoping);
        putBinding(new InstanceBindingImpl<T>(injector, key, source, scopedFactory, injectionPoints,
            instance));
        return true;
      }

      @Override
      public Boolean visit(ProviderInstanceBinding<? extends T> binding) {
        prepareBinding();
        javax.inject.Provider<? extends T> provider = binding.getUserSuppliedProvider();
        Set<InjectionPoint> injectionPoints = binding.getInjectionPoints();
        Initializable<? extends javax.inject.Provider<? extends T>> initializable =
            initializer.<javax.inject.Provider<? extends T>>requestInjection(
                injector, provider, null, source, injectionPoints);
        // always visited with Binding<T>
        @SuppressWarnings("unchecked") 
        InternalFactory<T> factory = new InternalFactoryToInitializableAdapter<T>(
            initializable, source, !injector.options.disableCircularProxies,
            injector.provisionListenerStore.get((ProviderInstanceBinding<T>)binding));
        InternalFactory<? extends T> scopedFactory
            = Scoping.scope(key, injector, factory, source, scoping);
        putBinding(new ProviderInstanceBindingImpl<T>(injector, key, source, scopedFactory, scoping,
            provider, injectionPoints));
        return true;
      }

      @Override
      public Boolean visit(ProviderKeyBinding<? extends T> binding) {
        prepareBinding();
        Key<? extends javax.inject.Provider<? extends T>> providerKey = binding.getProviderKey();
        // always visited with Binding<T>
        @SuppressWarnings("unchecked") 
        BoundProviderFactory<T> boundProviderFactory = new BoundProviderFactory<T>(
            injector, providerKey, source, !injector.options.disableCircularProxies,
            injector.provisionListenerStore.get((ProviderKeyBinding<T>) binding));
        bindingData.addCreationListener(boundProviderFactory);
        InternalFactory<? extends T> scopedFactory = Scoping.scope(
            key, injector, (InternalFactory<? extends T>) boundProviderFactory, source, scoping);
        putBinding(new LinkedProviderBindingImpl<T>(
            injector, key, source, scopedFactory, scoping, providerKey));
        return true;
      }

      @Override
      public Boolean visit(LinkedKeyBinding<? extends T> binding) {
        prepareBinding();
        Key<? extends T> linkedKey = binding.getLinkedKey();
        if (key.equals(linkedKey)) {
          errors.recursiveBinding();
        }

        FactoryProxy<T> factory = new FactoryProxy<T>(injector, key, linkedKey, source);
        bindingData.addCreationListener(factory);
        InternalFactory<? extends T> scopedFactory
            = Scoping.scope(key, injector, factory, source, scoping);
        putBinding(
            new LinkedBindingImpl<T>(injector, key, source, scopedFactory, scoping, linkedKey));
        return true;
      }

      @Override
      public Boolean visit(UntargettedBinding<? extends T> untargetted) {
        return false;
      }

      @Override
      public Boolean visit(ExposedBinding<? extends T> binding) {
        throw new IllegalArgumentException("Cannot apply a non-module element");
      }
      
      @Override
      public Boolean visit(ConvertedConstantBinding<? extends T> binding) {
        throw new IllegalArgumentException("Cannot apply a non-module element");
      }
      
      @Override
      public Boolean visit(ProviderBinding<? extends T> binding) {
        throw new IllegalArgumentException("Cannot apply a non-module element");
      }
      
      @Override
      protected Boolean visitOther(Binding<? extends T> binding) {
        throw new IllegalStateException("BindingProcessor should override all visitations");
      }
    });
  }

  @Override public Boolean visit(PrivateElements privateElements) {
    for (Key<?> key : privateElements.getExposedKeys()) {
      bindExposed(privateElements, key);
    }
    return false; // leave the private elements for the PrivateElementsProcessor to handle
  }

  private <T> void bindExposed(PrivateElements privateElements, Key<T> key) {
    ExposedKeyFactory<T> exposedKeyFactory = new ExposedKeyFactory<T>(key, privateElements);
    bindingData.addCreationListener(exposedKeyFactory);
    putBinding(new ExposedBindingImpl<T>(
        injector, privateElements.getExposedSource(key), key, exposedKeyFactory, privateElements));
  }
}
