/**
 * 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.common.base.Objects;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.Scope;
import com.google.inject.Scopes;
import com.google.inject.Singleton;
import com.google.inject.Stage;
import com.google.inject.binder.ScopedBindingBuilder;
import com.google.inject.spi.BindingScopingVisitor;

import java.lang.annotation.Annotation;

/**
 * References a scope, either directly (as a scope instance), or indirectly (as a scope annotation).
 * The scope's eager or laziness is also exposed.
 *
 * @author jessewilson@google.com (Jesse Wilson)
 */
public abstract class Scoping {

  /**
   * No scoping annotation has been applied. Note that this is different from {@code
   * in(Scopes.NO_SCOPE)}, where the 'NO_SCOPE' has been explicitly applied.
   */
  public static final Scoping UNSCOPED = new Scoping() {
    public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
      return visitor.visitNoScoping();
    }

    @Override public Scope getScopeInstance() {
      return Scopes.NO_SCOPE;
    }

    @Override public String toString() {
      return Scopes.NO_SCOPE.toString();
    }

    public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
      // do nothing
    }
  };

  public static final Scoping SINGLETON_ANNOTATION = new Scoping() {
    public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
      return visitor.visitScopeAnnotation(Singleton.class);
    }

    @Override public Class<? extends Annotation> getScopeAnnotation() {
      return Singleton.class;
    }

    @Override public String toString() {
      return Singleton.class.getName();
    }

    public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
      scopedBindingBuilder.in(Singleton.class);
    }
  };

  public static final Scoping SINGLETON_INSTANCE = new Scoping() {
    public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
      return visitor.visitScope(Scopes.SINGLETON);
    }

    @Override public Scope getScopeInstance() {
      return Scopes.SINGLETON;
    }

    @Override public String toString() {
      return Scopes.SINGLETON.toString();
    }

    public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
      scopedBindingBuilder.in(Scopes.SINGLETON);
    }
  };

  public static final Scoping EAGER_SINGLETON = new Scoping() {
    public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
      return visitor.visitEagerSingleton();
    }

    @Override public Scope getScopeInstance() {
      return Scopes.SINGLETON;
    }

    @Override public String toString() {
      return "eager singleton";
    }

    public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
      scopedBindingBuilder.asEagerSingleton();
    }
  };

  public static Scoping forAnnotation(final Class<? extends Annotation> scopingAnnotation) {
    if (scopingAnnotation == Singleton.class
        || scopingAnnotation == javax.inject.Singleton.class) {
      return SINGLETON_ANNOTATION;
    }

    return new Scoping() {
      public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
        return visitor.visitScopeAnnotation(scopingAnnotation);
      }

      @Override public Class<? extends Annotation> getScopeAnnotation() {
        return scopingAnnotation;
      }

      @Override public String toString() {
        return scopingAnnotation.getName();
      }

      public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
        scopedBindingBuilder.in(scopingAnnotation);
      }
    };
  }

  public static Scoping forInstance(final Scope scope) {
    if (scope == Scopes.SINGLETON) {
      return SINGLETON_INSTANCE;
    }

    return new Scoping() {
      public <V> V acceptVisitor(BindingScopingVisitor<V> visitor) {
        return visitor.visitScope(scope);
      }

      @Override public Scope getScopeInstance() {
        return scope;
      }

      @Override public String toString() {
        return scope.toString();
      }

      public void applyTo(ScopedBindingBuilder scopedBindingBuilder) {
        scopedBindingBuilder.in(scope);
      }
    };
  }

  /**
   * Returns true if this scope was explicitly applied. If no scope was explicitly applied then the
   * scoping annotation will be used.
   */
  public boolean isExplicitlyScoped() {
    return this != UNSCOPED;
  }

  /**
   * Returns true if this is the default scope. In this case a new instance will be provided for
   * each injection.
   */
  public boolean isNoScope() {
    return getScopeInstance() == Scopes.NO_SCOPE;
  }

  /**
   * Returns true if this scope is a singleton that should be loaded eagerly in {@code stage}.
   */
  public boolean isEagerSingleton(Stage stage) {
    if (this == EAGER_SINGLETON) {
      return true;
    }

    if (stage == Stage.PRODUCTION) {
      return this == SINGLETON_ANNOTATION || this == SINGLETON_INSTANCE;
    }

    return false;
  }

  /**
   * Returns the scope instance, or {@code null} if that isn't known for this instance.
   */
  public Scope getScopeInstance() {
    return null;
  }

  /**
   * Returns the scope annotation, or {@code null} if that isn't known for this instance.
   */
  public Class<? extends Annotation> getScopeAnnotation() {
    return null;
  }
  
  @Override
  public boolean equals(Object obj) {
    if(obj instanceof Scoping) {
      Scoping o = (Scoping)obj;
      return Objects.equal(getScopeAnnotation(), o.getScopeAnnotation())
        && Objects.equal(getScopeInstance(), o.getScopeInstance());
    } else {
      return false;
    }
  }
  
  @Override
  public int hashCode() {
    return Objects.hashCode(getScopeAnnotation(), getScopeInstance());
  }

  public abstract <V> V acceptVisitor(BindingScopingVisitor<V> visitor);

  public abstract void applyTo(ScopedBindingBuilder scopedBindingBuilder);

  private Scoping() {}

  /** Scopes an internal factory. */
  static <T> InternalFactory<? extends T> scope(Key<T> key, InjectorImpl injector,
      InternalFactory<? extends T> creator, Object source, Scoping scoping) {

    if (scoping.isNoScope()) {
      return creator;
    }

    Scope scope = scoping.getScopeInstance();

    Provider<T> scoped
        = scope.scope(key, new ProviderToInternalFactoryAdapter<T>(injector, creator));
    return new InternalFactoryToProviderAdapter<T>(scoped, source);
  }

  /**
   * Replaces annotation scopes with instance scopes using the Injector's annotation-to-instance
   * map. If the scope annotation has no corresponding instance, an error will be added and unscoped
   * will be retuned.
   */
  static Scoping makeInjectable(Scoping scoping, InjectorImpl injector, Errors errors) {
    Class<? extends Annotation> scopeAnnotation = scoping.getScopeAnnotation();
    if (scopeAnnotation == null) {
      return scoping;
    }

    Scope scope = injector.state.getScope(scopeAnnotation);
    if (scope != null) {
      return forInstance(scope);
    }

    errors.scopeNotFound(scopeAnnotation);
    return UNSCOPED;
  }
}
