/**
 * 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.inject.Key;
import com.google.inject.Stage;
import com.google.inject.TypeLiteral;
import com.google.inject.internal.util.Lists;
import com.google.inject.internal.util.Maps;
import static com.google.inject.internal.util.Preconditions.checkNotNull;
import com.google.inject.spi.InjectionPoint;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;

/**
 * Manages and injects instances at injector-creation time. This is made more complicated by
 * instances that request other instances while they're being injected. We overcome this by using
 * {@link Initializable}, which attempts to perform injection before use.
 *
 * @author jessewilson@google.com (Jesse Wilson)
 */
final class Initializer {
  /** the only thread that we'll use to inject members. */
  private final Thread creatingThread = Thread.currentThread();

  /** zero means everything is injected. */
  private final CountDownLatch ready = new CountDownLatch(1);

  /** Maps instances that need injection to a source that registered them */
  private final Map<Object, InjectableReference<?>> pendingInjection = Maps.newIdentityHashMap();

  /**
   * Registers an instance for member injection when that step is performed.
   *
   * @param instance an instance that optionally has members to be injected (each annotated with
   *      @Inject).
   * @param key a key to use for keeping the state of the dependency chain
   * @param source the source location that this injection was requested
   */
  <T> Initializable<T> requestInjection(InjectorImpl injector, T instance, Key<T> key,
      Object source, Set<InjectionPoint> injectionPoints) {
    checkNotNull(source);

    // short circuit if the object has no injections
    if (instance == null
        || (injectionPoints.isEmpty() && !injector.membersInjectorStore.hasTypeListeners())) {
      return Initializables.of(instance);
    }

    InjectableReference<T> initializable = new InjectableReference<T>(injector, instance, key, source);
    pendingInjection.put(instance, initializable);
    return initializable;
  }

  /**
   * Prepares member injectors for all injected instances. This prompts Guice to do static analysis
   * on the injected instances.
   */
  void validateOustandingInjections(Errors errors) {
    for (InjectableReference<?> reference : pendingInjection.values()) {
      try {
        reference.validate(errors);
      } catch (ErrorsException e) {
        errors.merge(e.getErrors());
      }
    }
  }

  /**
   * Performs creation-time injections on all objects that require it. Whenever fulfilling an
   * injection depends on another object that requires injection, we inject it first. If the two
   * instances are codependent (directly or transitively), ordering of injection is arbitrary.
   */
  void injectAll(final Errors errors) {
    // loop over a defensive copy since ensureInjected() mutates the set. Unfortunately, that copy
    // is made complicated by a bug in IBM's JDK, wherein entrySet().toArray(Object[]) doesn't work
    for (InjectableReference<?> reference : Lists.newArrayList(pendingInjection.values())) {
      try {
        reference.get(errors);
      } catch (ErrorsException e) {
        errors.merge(e.getErrors());
      }
    }

    if (!pendingInjection.isEmpty()) {
      throw new AssertionError("Failed to satisfy " + pendingInjection);
    }

    ready.countDown();
  }

  private class InjectableReference<T> implements Initializable<T> {
    private final InjectorImpl injector;
    private final T instance;
    private final Object source;
    private final Key<T> key;
    private MembersInjectorImpl<T> membersInjector;

    public InjectableReference(InjectorImpl injector, T instance, Key<T> key, Object source) {
      this.injector = injector;
      this.key = key; // possibly null!
      this.instance = checkNotNull(instance, "instance");
      this.source = checkNotNull(source, "source");
    }

    public void validate(Errors errors) throws ErrorsException {
      @SuppressWarnings("unchecked") // the type of 'T' is a TypeLiteral<T>
          TypeLiteral<T> type = TypeLiteral.get((Class<T>) instance.getClass());
      membersInjector = injector.membersInjectorStore.get(type, errors.withSource(source));
    }

    /**
     * Reentrant. If {@code instance} was registered for injection at injector-creation time, this
     * method will ensure that all its members have been injected before returning.
     */
    public T get(Errors errors) throws ErrorsException {
      if (ready.getCount() == 0) {
        return instance;
      }

      // just wait for everything to be injected by another thread
      if (Thread.currentThread() != creatingThread) {
        try {
          ready.await();
          return instance;
        } catch (InterruptedException e) {
          // Give up, since we don't know if our injection is ready
          throw new RuntimeException(e);
        }
      }

      // toInject needs injection, do it right away. we only do this once, even if it fails
      if (pendingInjection.remove(instance) != null) {
        // if in Stage.TOOL, we only want to inject & notify toolable injection points.
        // (otherwise we'll inject all of them)
        membersInjector.injectAndNotify(instance, errors.withSource(source), key, source, 
            injector.options.stage == Stage.TOOL);
      }

      return instance;
    }

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