/**
 * 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.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.inject.Binding;
import com.google.inject.Key;
import com.google.inject.Scope;
import com.google.inject.TypeLiteral;
import com.google.inject.spi.ProvisionListenerBinding;
import com.google.inject.spi.ScopeBinding;
import com.google.inject.spi.TypeConverterBinding;
import com.google.inject.spi.TypeListenerBinding;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author jessewilson@google.com (Jesse Wilson)
 */
final class InheritingState implements State {

  private final State parent;

  // Must be a linked hashmap in order to preserve order of bindings in Modules.
  private final Map<Key<?>, Binding<?>> explicitBindingsMutable = Maps.newLinkedHashMap();
  private final Map<Key<?>, Binding<?>> explicitBindings
      = Collections.unmodifiableMap(explicitBindingsMutable);
  private final Map<Class<? extends Annotation>, ScopeBinding> scopes = Maps.newHashMap();
  private final List<TypeConverterBinding> converters = Lists.newArrayList();
  /*if[AOP]*/
  private final List<MethodAspect> methodAspects = Lists.newArrayList();
  /*end[AOP]*/
  private final List<TypeListenerBinding> typeListenerBindings = Lists.newArrayList();
  private final List<ProvisionListenerBinding> provisionListenerBindings = Lists.newArrayList(); 
  private final WeakKeySet blacklistedKeys;
  private final Object lock;
  private final Object singletonCreationLock;

  InheritingState(State parent) {
    this.parent = checkNotNull(parent, "parent");
    this.lock = (parent == State.NONE) ? this : parent.lock();
    this.singletonCreationLock =
        (parent == State.NONE) ? new Object() : parent.singletonCreationLock();
    this.blacklistedKeys = new WeakKeySet(lock);
  }

  public State parent() {
    return parent;
  }

  @SuppressWarnings("unchecked") // we only put in BindingImpls that match their key types
  public <T> BindingImpl<T> getExplicitBinding(Key<T> key) {
    Binding<?> binding = explicitBindings.get(key);
    return binding != null ? (BindingImpl<T>) binding : parent.getExplicitBinding(key);
  }

  public Map<Key<?>, Binding<?>> getExplicitBindingsThisLevel() {
    return explicitBindings;
  }

  public void putBinding(Key<?> key, BindingImpl<?> binding) {
    explicitBindingsMutable.put(key, binding);
  }

  public ScopeBinding getScopeBinding(Class<? extends Annotation> annotationType) {
    ScopeBinding scopeBinding = scopes.get(annotationType);
    return scopeBinding != null ? scopeBinding : parent.getScopeBinding(annotationType);
  }

  public void putScopeBinding(Class<? extends Annotation> annotationType, ScopeBinding scope) {
    scopes.put(annotationType, scope);
  }

  public Iterable<TypeConverterBinding> getConvertersThisLevel() {
    return converters;
  }

  public void addConverter(TypeConverterBinding typeConverterBinding) {
    converters.add(typeConverterBinding);
  }

  public TypeConverterBinding getConverter(
      String stringValue, TypeLiteral<?> type, Errors errors, Object source) {
    TypeConverterBinding matchingConverter = null;
    for (State s = this; s != State.NONE; s = s.parent()) {
      for (TypeConverterBinding converter : s.getConvertersThisLevel()) {
        if (converter.getTypeMatcher().matches(type)) {
          if (matchingConverter != null) {
            errors.ambiguousTypeConversion(stringValue, source, type, matchingConverter, converter);
          }
          matchingConverter = converter;
        }
      }
    }
    return matchingConverter;
  }

  /*if[AOP]*/
  public void addMethodAspect(MethodAspect methodAspect) {
    methodAspects.add(methodAspect);
  }

  public ImmutableList<MethodAspect> getMethodAspects() {
    return new ImmutableList.Builder<MethodAspect>()
        .addAll(parent.getMethodAspects())
        .addAll(methodAspects)
        .build();
  }
  /*end[AOP]*/

  public void addTypeListener(TypeListenerBinding listenerBinding) {
    typeListenerBindings.add(listenerBinding);
  }

  public List<TypeListenerBinding> getTypeListenerBindings() {
    List<TypeListenerBinding> parentBindings = parent.getTypeListenerBindings();
    List<TypeListenerBinding> result
        = new ArrayList<TypeListenerBinding>(parentBindings.size() + 1);
    result.addAll(parentBindings);
    result.addAll(typeListenerBindings);
    return result;
  }
  
  public void addProvisionListener(ProvisionListenerBinding listenerBinding) {
    provisionListenerBindings.add(listenerBinding);
  }

  public List<ProvisionListenerBinding> getProvisionListenerBindings() {
    List<ProvisionListenerBinding> parentBindings = parent.getProvisionListenerBindings();
    List<ProvisionListenerBinding> result
        = new ArrayList<ProvisionListenerBinding>(parentBindings.size() + 1);
    result.addAll(parentBindings);
    result.addAll(provisionListenerBindings);
    return result;
  }

  public void blacklist(Key<?> key, State state, Object source) {
    parent.blacklist(key, state, source);
    blacklistedKeys.add(key, state, source);
  }

  public boolean isBlacklisted(Key<?> key) {
    return blacklistedKeys.contains(key);
  }
  
  public Set<Object> getSourcesForBlacklistedKey(Key<?> key) {
    return blacklistedKeys.getSources(key);
  }

  public Object lock() {
    return lock;
  }

  public Object singletonCreationLock() {
    return singletonCreationLock;
  }

  public Map<Class<? extends Annotation>, Scope> getScopes() {
    ImmutableMap.Builder<Class<? extends Annotation>, Scope> builder = ImmutableMap.builder();
    for (Map.Entry<Class<? extends Annotation>, ScopeBinding> entry : scopes.entrySet()) {
      builder.put(entry.getKey(), entry.getValue().getScope());
    }
    return builder.build();
  }
}
