/**
 * 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);
    }
  }
}