/**
 * Copyright (C) 2011 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.common.collect.ImmutableSet;
import com.google.inject.AbstractModule;
import com.google.inject.Binder;
import com.google.inject.Binding;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.MembersInjector;
import com.google.inject.Module;
import com.google.inject.Provider;
import com.google.inject.Scope;
import com.google.inject.Stage;
import com.google.inject.TypeLiteral;
import com.google.inject.spi.DefaultBindingTargetVisitor;

import java.util.Set;

/**
 * Guarantees that processing of Binding elements happens in a sane way.
 * 
 * @author sameb@google.com (Sam Berlin)
 */
abstract class AbstractBindingProcessor extends AbstractProcessor {

  // It's unfortunate that we have to maintain a blacklist of specific
  // classes, but we can't easily block the whole package because of
  // all our unit tests.
  private static final Set<Class<?>> FORBIDDEN_TYPES = ImmutableSet.<Class<?>>of(
      AbstractModule.class,
      Binder.class,
      Binding.class,
      Injector.class,
      Key.class,
      MembersInjector.class,
      Module.class,
      Provider.class,
      Scope.class,
      Stage.class,
      TypeLiteral.class);
  
  protected final ProcessedBindingData bindingData;
  
  AbstractBindingProcessor(Errors errors, ProcessedBindingData bindingData) {
    super(errors);
    this.bindingData = bindingData;
  }

  protected <T> UntargettedBindingImpl<T> invalidBinding(
      InjectorImpl injector, Key<T> key, Object source) {
    return new UntargettedBindingImpl<T>(injector, key, source);
  }
  
  protected void putBinding(BindingImpl<?> binding) {
    Key<?> key = binding.getKey();

    Class<?> rawType = key.getTypeLiteral().getRawType();
    if (FORBIDDEN_TYPES.contains(rawType)) {
      errors.cannotBindToGuiceType(rawType.getSimpleName());
      return;
    }

    BindingImpl<?> original = injector.getExistingBinding(key);
    if (original != null) {
      // If it failed because of an explicit duplicate binding...
      if (injector.state.getExplicitBinding(key) != null) {
        try {
          if(!isOkayDuplicate(original, binding, injector.state)) {
            errors.bindingAlreadySet(key, original.getSource());
            return;
          }
        } catch(Throwable t) {
          errors.errorCheckingDuplicateBinding(key, original.getSource(), t);
          return;
        }
      } else {
        // Otherwise, it failed because of a duplicate JIT binding
        // in the parent
        errors.jitBindingAlreadySet(key);
        return;
      }
    }

    // prevent the parent from creating a JIT binding for this key
    injector.state.parent().blacklist(key, injector.state, binding.getSource());
    injector.state.putBinding(key, binding);
  }

  /**
   * We tolerate duplicate bindings if one exposes the other or if the two bindings
   * are considered duplicates (see {@link Bindings#areDuplicates(BindingImpl, BindingImpl)}.
   *
   * @param original the binding in the parent injector (candidate for an exposing binding)
   * @param binding the binding to check (candidate for the exposed binding)
   */
  private boolean isOkayDuplicate(BindingImpl<?> original, BindingImpl<?> binding, State state) {
    if (original instanceof ExposedBindingImpl) {
      ExposedBindingImpl exposed = (ExposedBindingImpl) original;
      InjectorImpl exposedFrom = (InjectorImpl) exposed.getPrivateElements().getInjector();
      return (exposedFrom == binding.getInjector());
    } else {
      original = (BindingImpl<?>)state.getExplicitBindingsThisLevel().get(binding.getKey());
      // If no original at this level, the original was on a parent, and we don't
      // allow deduplication between parents & children.
      if(original == null) {
        return false;
      } else {
        return original.equals(binding);
      }
    }
  }
  
  private <T> void validateKey(Object source, Key<T> key) {
    Annotations.checkForMisplacedScopeAnnotations(
        key.getTypeLiteral().getRawType(), source, errors);
  }
  
  /** 
   * Processor for visiting bindings.  Each overriden method that wants to
   * actually process the binding should call prepareBinding first.
   */
  abstract class Processor<T, V> extends DefaultBindingTargetVisitor<T, V> {
    final Object source;
    final Key<T> key;
    final Class<? super T> rawType;
    Scoping scoping;
    
    Processor(BindingImpl<T> binding) {
      source = binding.getSource();
      key = binding.getKey();
      rawType = key.getTypeLiteral().getRawType();
      scoping = binding.getScoping();
    }
    
    protected void prepareBinding() {      
      validateKey(source, key);
      scoping = Scoping.makeInjectable(scoping, injector, errors);
    }

    protected void scheduleInitialization(final BindingImpl<?> binding) {
      bindingData.addUninitializedBinding(new Runnable() {
        public void run() {
          try {
            binding.getInjector().initializeBinding(binding, errors.withSource(source));
          } catch (ErrorsException e) {
            errors.merge(e.getErrors());
          }
        }
      });
    }
  }
}
