/**
 * 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.Key;
import com.google.inject.Scope;
import static com.google.inject.internal.Preconditions.checkNotNull;
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);
    }
  }
}