/**
 * Copyright (C) 2009 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.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Key;
import com.google.inject.MembersInjector;
import com.google.inject.TypeLiteral;
import com.google.inject.internal.ProvisionListenerStackCallback.ProvisionCallback;
import com.google.inject.spi.InjectionListener;
import com.google.inject.spi.InjectionPoint;

/**
 * Injects members of instances of a given type.
 *
 * @author jessewilson@google.com (Jesse Wilson)
 */
final class MembersInjectorImpl<T> implements MembersInjector<T> {
  private final TypeLiteral<T> typeLiteral;
  private final InjectorImpl injector;
  private final ImmutableList<SingleMemberInjector> memberInjectors;
  private final ImmutableSet<MembersInjector<? super T>> userMembersInjectors;
  private final ImmutableSet<InjectionListener<? super T>> injectionListeners;
  /*if[AOP]*/
  private final ImmutableList<MethodAspect> addedAspects;
  /*end[AOP]*/

  MembersInjectorImpl(InjectorImpl injector, TypeLiteral<T> typeLiteral,
      EncounterImpl<T> encounter, ImmutableList<SingleMemberInjector> memberInjectors) {
    this.injector = injector;
    this.typeLiteral = typeLiteral;
    this.memberInjectors = memberInjectors;
    this.userMembersInjectors = encounter.getMembersInjectors();
    this.injectionListeners = encounter.getInjectionListeners();
    /*if[AOP]*/
    this.addedAspects = encounter.getAspects();
    /*end[AOP]*/
  }

  public ImmutableList<SingleMemberInjector> getMemberInjectors() {
    return memberInjectors;
  }

  public void injectMembers(T instance) {
    Errors errors = new Errors(typeLiteral);
    try {
      injectAndNotify(instance, errors, null, null, typeLiteral, false);
    } catch (ErrorsException e) {
      errors.merge(e.getErrors());
    }

    errors.throwProvisionExceptionIfErrorsExist();
  }

  void injectAndNotify(final T instance,
      final Errors errors,
      final Key<T> key, // possibly null!
      final ProvisionListenerStackCallback<T> provisionCallback, // possibly null!
      final Object source,
      final boolean toolableOnly) throws ErrorsException {
    if (instance == null) {
      return;
    }

    injector.callInContext(new ContextualCallable<Void>() {
      @Override
      public Void call(final InternalContext context) throws ErrorsException {
        context.pushState(key, source);
        try {
          if (provisionCallback != null && provisionCallback.hasListeners()) {
            provisionCallback.provision(errors, context, new ProvisionCallback<T>() {
              @Override public T call() {
                injectMembers(instance, errors, context, toolableOnly);
                return instance;
              }
            });
          } else {
            injectMembers(instance, errors, context, toolableOnly);
          }
        } finally {
          context.popState();
        }
        return null;
      }
    });

    // TODO: We *could* notify listeners too here,
    // but it's not clear if we want to.  There's no way to know
    // if a MembersInjector from the usersMemberInjector list wants
    // toolable injections, so do we really want to notify
    // about injection?  (We could take a strategy of only notifying
    // if atleast one InjectionPoint was toolable, in which case
    // the above callInContext could return 'true' if it injected
    // anything.)
    if(!toolableOnly) {
      notifyListeners(instance, errors);
    }
  }

  void notifyListeners(T instance, Errors errors) throws ErrorsException {
    int numErrorsBefore = errors.size();
    for (InjectionListener<? super T> injectionListener : injectionListeners) {
      try {
        injectionListener.afterInjection(instance);
      } catch (RuntimeException e) {
        errors.errorNotifyingInjectionListener(injectionListener, typeLiteral, e);
      }
    }
    errors.throwIfNewErrors(numErrorsBefore);
  }

  void injectMembers(T t, Errors errors, InternalContext context, boolean toolableOnly) {
    // optimization: use manual for/each to save allocating an iterator here
    for (int i = 0, size = memberInjectors.size(); i < size; i++) {
      SingleMemberInjector injector = memberInjectors.get(i);
      if(!toolableOnly || injector.getInjectionPoint().isToolable()) {
        injector.inject(errors, context, t);
      }
    }

    // TODO: There's no way to know if a user's MembersInjector wants toolable injections.
    if(!toolableOnly) {
      for (MembersInjector<? super T> userMembersInjector : userMembersInjectors) {
        try {
          userMembersInjector.injectMembers(t);
        } catch (RuntimeException e) {
          errors.errorInUserInjector(userMembersInjector, typeLiteral, e);
        }
      }
    }
  }

  @Override public String toString() {
    return "MembersInjector<" + typeLiteral + ">";
  }

  public ImmutableSet<InjectionPoint> getInjectionPoints() {
    ImmutableSet.Builder<InjectionPoint> builder = ImmutableSet.builder();
    for (SingleMemberInjector memberInjector : memberInjectors) {
      builder.add(memberInjector.getInjectionPoint());
    }
    return builder.build();
  }

  /*if[AOP]*/
  public ImmutableList<MethodAspect> getAddedAspects() {
    return addedAspects;
  }
  /*end[AOP]*/
}
