/**
 * 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 static com.google.common.base.Preconditions.checkNotNull;
import com.google.inject.Binder;
import com.google.inject.Key;
import com.google.inject.Scope;
import com.google.inject.spi.Element;
import com.google.inject.spi.InstanceBinding;
import java.lang.annotation.Annotation;
import java.util.List;

/**
 * Bind a value or constant.
 *
 * @author jessewilson@google.com (Jesse Wilson)
 */
public abstract class AbstractBindingBuilder<T> {

  public static final String IMPLEMENTATION_ALREADY_SET = "Implementation is set more than once.";
  public static final String SINGLE_INSTANCE_AND_SCOPE
      = "Setting the scope is not permitted when binding to a single instance.";
  public static final String SCOPE_ALREADY_SET = "Scope is set more than once.";
  public static final String BINDING_TO_NULL = "Binding to null instances is not allowed. "
      + "Use toProvider(Providers.of(null)) if this is your intended behaviour.";
  public static final String CONSTANT_VALUE_ALREADY_SET = "Constant value is set more than once.";
  public static final String ANNOTATION_ALREADY_SPECIFIED
      = "More than one annotation is specified for this binding.";

  protected static final Key<?> NULL_KEY = Key.get(Void.class);

  protected List<Element> elements;
  protected int position;
  protected final Binder binder;
  private BindingImpl<T> binding;

  public AbstractBindingBuilder(Binder binder, List<Element> elements, Object source, Key<T> key) {
    this.binder = binder;
    this.elements = elements;
    this.position = elements.size();
    this.binding = new UntargettedBindingImpl<T>(source, key, Scoping.UNSCOPED);
    elements.add(position, this.binding);
  }

  protected BindingImpl<T> getBinding() {
    return binding;
  }

  protected BindingImpl<T> setBinding(BindingImpl<T> binding) {
    this.binding = binding;
    elements.set(position, binding);
    return binding;
  }

  /** Sets the binding to a copy with the specified annotation on the bound key */
  protected BindingImpl<T> annotatedWithInternal(Class<? extends Annotation> annotationType) {
    checkNotNull(annotationType, "annotationType");
    checkNotAnnotated();
    return setBinding(binding.withKey(
        Key.get(this.binding.getKey().getTypeLiteral(), annotationType)));
  }

  /** Sets the binding to a copy with the specified annotation on the bound key */
  protected BindingImpl<T> annotatedWithInternal(Annotation annotation) {
    checkNotNull(annotation, "annotation");
    checkNotAnnotated();
    return setBinding(binding.withKey(
        Key.get(this.binding.getKey().getTypeLiteral(), annotation)));
  }

  public void in(final Class<? extends Annotation> scopeAnnotation) {
    checkNotNull(scopeAnnotation, "scopeAnnotation");
    checkNotScoped();
    setBinding(getBinding().withScoping(Scoping.forAnnotation(scopeAnnotation)));
  }

  public void in(final Scope scope) {
    checkNotNull(scope, "scope");
    checkNotScoped();
    setBinding(getBinding().withScoping(Scoping.forInstance(scope)));
  }

  public void asEagerSingleton() {
    checkNotScoped();
    setBinding(getBinding().withScoping(Scoping.EAGER_SINGLETON));
  }

  protected boolean keyTypeIsSet() {
    return !Void.class.equals(binding.getKey().getTypeLiteral().getType());
  }

  protected void checkNotTargetted() {
    if (!(binding instanceof UntargettedBindingImpl)) {
      binder.addError(IMPLEMENTATION_ALREADY_SET);
    }
  }

  protected void checkNotAnnotated() {
    if (binding.getKey().getAnnotationType() != null) {
      binder.addError(ANNOTATION_ALREADY_SPECIFIED);
    }
  }

  protected void checkNotScoped() {
    // Scoping isn't allowed when we have only one instance.
    if (binding instanceof InstanceBinding) {
      binder.addError(SINGLE_INSTANCE_AND_SCOPE);
      return;
    }

    if (binding.getScoping().isExplicitlyScoped()) {
      binder.addError(SCOPE_ALREADY_SET);
    }
  }
}