/**
 * 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.inject.MembersInjector;
import com.google.inject.TypeLiteral;
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 ImmutableList<MembersInjector<? super T>> userMembersInjectors;
  private final ImmutableList<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);
    } catch (ErrorsException e) {
      errors.merge(e.getErrors());
    }

    errors.throwProvisionExceptionIfErrorsExist();
  }

  void injectAndNotify(final T instance, final Errors errors) throws ErrorsException {
    if (instance == null) {
      return;
    }

    injector.callInContext(new ContextualCallable<Void>() {
      public Void call(InternalContext context) throws ErrorsException {
        injectMembers(instance, errors, context);
        return null;
      }
    });

    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) {
    // optimization: use manual for/each to save allocating an iterator here
    for (int i = 0, size = memberInjectors.size(); i < size; i++) {
      memberInjectors.get(i).inject(errors, context, t);
    }

    // optimization: use manual for/each to save allocating an iterator here
    for (int i = 0, size = userMembersInjectors.size(); i < size; i++) {
      MembersInjector<? super T> userMembersInjector = userMembersInjectors.get(i);
      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]*/
}
