/**
 * Copyright (C) 2006 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;

import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.inject.Reflection.Factory;
import static com.google.inject.Scopes.SINGLETON;
import com.google.inject.commands.Command;
import com.google.inject.commands.CommandRecorder;
import com.google.inject.internal.Errors;
import com.google.inject.internal.ErrorsException;
import com.google.inject.internal.SourceProvider;
import com.google.inject.internal.Stopwatch;
import com.google.inject.spi.InjectionPoint;
import java.lang.reflect.Member;
import java.util.List;
import java.util.logging.Logger;

/**
 * Builds a dependency injection {@link Injector}.
 *
 * @author crazybob@google.com (Bob Lee)
 * @author jessewilson@google.com (Jesse Wilson)
 */
class InjectorBuilder {

  private final Stopwatch stopwatch = new Stopwatch();

  private Injector parent;
  private Stage stage;
  private Factory reflectionFactory = new RuntimeReflectionFactory();
  private final List<Module> modules = Lists.newLinkedList();

  private InjectorImpl injector;
  private Errors errors = new Errors();

  private final List<Command> commands = Lists.newArrayList();

  private BindCommandProcessor bindCommandProcesor;
  private RequestInjectionCommandProcessor requestInjectionCommandProcessor;

  /**
   * @param stage we're running in. If the stage is {@link Stage#PRODUCTION}, we will eagerly load
   * singletons.
   */
  InjectorBuilder stage(Stage stage) {
    this.stage = stage;
    return this;
  }

  InjectorBuilder usingReflectionFactory(Factory reflectionFactory) {
    this.reflectionFactory = reflectionFactory;
    return this;
  }

  InjectorBuilder parentInjector(Injector parent) {
    this.parent = parent;
    return this;
  }

  InjectorBuilder addModules(Iterable<? extends Module> modules) {
    for (Module module : modules) {
      this.modules.add(module);
    }
    return this;
  }

  Injector build() {
    if (injector != null) {
      throw new AssertionError("Already built, builders are not reusable.");
    }

    injector = new InjectorImpl(parent);

    modules.add(0, new BuiltInModule(injector, stage));

    CommandRecorder commandRecorder = new CommandRecorder();
    commandRecorder.setCurrentStage(stage);
    commands.addAll(commandRecorder.recordCommands(modules));

    buildCoreInjector();

    validate();

    errors.throwCreationExceptionIfErrorsExist();

    // If we're in the tool stage, stop here. Don't eagerly inject or load
    // anything.
    if (stage == Stage.TOOL) {
      // TODO: Wrap this and prevent usage of anything besides getBindings().
      return injector;
    }

    fulfillInjectionRequests();

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

    return injector;
  }

  /** Builds the injector. */
  private void buildCoreInjector() {
    new ErrorsCommandProcessor(errors)
        .processCommands(commands);

    BindInterceptorCommandProcessor bindInterceptorCommandProcessor
        = new BindInterceptorCommandProcessor(errors);
    bindInterceptorCommandProcessor.processCommands(commands);
    ConstructionProxyFactory proxyFactory = bindInterceptorCommandProcessor.createProxyFactory();
    injector.reflection = reflectionFactory.create(proxyFactory);
    stopwatch.resetAndLog("Interceptors creation");

    new ScopesCommandProcessor(errors, injector.scopes).processCommands(commands);
    stopwatch.resetAndLog("Scopes creation");

    new ConvertToTypesCommandProcessor(errors, injector.converters).processCommands(commands);
    stopwatch.resetAndLog("Converters creation");

    bindLogger();
    bindCommandProcesor = new BindCommandProcessor(errors,
        injector, injector.scopes, injector.explicitBindings,
        injector.outstandingInjections);
    bindCommandProcesor.processCommands(commands);
    bindCommandProcesor.createUntargettedBindings();
    stopwatch.resetAndLog("Binding creation");

    injector.index();
    stopwatch.resetAndLog("Binding indexing");

    requestInjectionCommandProcessor
        = new RequestInjectionCommandProcessor(errors, injector.outstandingInjections);
    requestInjectionCommandProcessor.processCommands(commands);
    stopwatch.resetAndLog("Static injection");
  }

  /** Validate everything that we can validate now that the injector is ready for use. */
  private void validate() {
    bindCommandProcesor.runCreationListeners(injector);
    stopwatch.resetAndLog("Validation");

    requestInjectionCommandProcessor.validate(injector);
    stopwatch.resetAndLog("Static validation");

    injector.validateOustandingInjections(errors);
    stopwatch.resetAndLog("Instance member validation");

    new GetProviderProcessor(errors, injector).processCommands(commands);
    stopwatch.resetAndLog("Provider verification");

    errors.throwCreationExceptionIfErrorsExist();
  }

  /** Inject everything that can be injected. */
  private void fulfillInjectionRequests() {
    requestInjectionCommandProcessor.injectMembers(injector);
    stopwatch.resetAndLog("Static member injection");

    injector.fulfillOutstandingInjections(errors);
    stopwatch.resetAndLog("Instance injection");
    errors.throwCreationExceptionIfErrorsExist();

    loadEagerSingletons();
    stopwatch.resetAndLog("Preloading");
    errors.throwCreationExceptionIfErrorsExist();
  }

  public void loadEagerSingletons() {
    // load eager singletons, or all singletons if we're in Stage.PRODUCTION.
    for (final BindingImpl<?> binding
        : Iterables.concat(injector.explicitBindings.values(), injector.jitBindings.values())) {
      if ((stage == Stage.PRODUCTION && binding.getScope() == Scopes.SINGLETON)
          || binding.getLoadStrategy() == LoadStrategy.EAGER) {
        try {
          injector.callInContext(new ContextualCallable<Void>() {
            public Void call(InternalContext context) {
              InjectionPoint<?> injectionPoint = InjectionPoint.newInstance(binding.key);
              context.setInjectionPoint(injectionPoint);
              errors.pushInjectionPoint(injectionPoint);
              try {
                binding.internalFactory.get(errors, context, injectionPoint);
              } catch (ErrorsException e) {
                errors.merge(e.getErrors());
              } finally {
                context.setInjectionPoint(null);
                errors.popInjectionPoint(injectionPoint);
              }

              return null;
            }
          });
        } catch (ErrorsException e) {
          throw new AssertionError();
        }
      }
    }
  }

  private static class BuiltInModule implements Module {
    final Injector injector;
    final Stage stage;

    private BuiltInModule(Injector injector, Stage stage) {
      this.injector = checkNotNull(injector, "injector");
      this.stage = checkNotNull(stage, "stage");
    }

    public void configure(Binder binder) {
      binder = binder.withSource(SourceProvider.UNKNOWN_SOURCE);

      binder.bind(Stage.class).toInstance(stage);
      binder.bindScope(Singleton.class, SINGLETON);
      // Create default bindings.
      // We use toProvider() instead of toInstance() to avoid infinite recursion
      // in toString().
      binder.bind(Injector.class).toProvider(new InjectorProvider(injector));
    }

    class InjectorProvider implements Provider<Injector> {
      final Injector injector;

      InjectorProvider(Injector injector) {
        this.injector = injector;
      }

      public Injector get() {
        return injector;
      }

      public String toString() {
        return "Provider<Injector>";
      }
    }
  }

  /**
   * The Logger is a special case because it knows the injection point of the injected member. It's
   * the only binding that does this.
   */
  private void bindLogger() {
    Key<Logger> key = Key.get(Logger.class);
    LoggerFactory loggerFactory = new LoggerFactory();
    injector.explicitBindings.put(key,
        new ProviderInstanceBindingImpl<Logger>(injector, key,
            SourceProvider.UNKNOWN_SOURCE, loggerFactory, Scopes.NO_SCOPE,
            loggerFactory, LoadStrategy.LAZY));
  }

  static class LoggerFactory implements InternalFactory<Logger>, Provider<Logger> {
    public Logger get(Errors errors, InternalContext context, InjectionPoint<?> injectionPoint) {
      Member member = injectionPoint.getMember();
      return member == null
          ? Logger.getAnonymousLogger()
          : Logger.getLogger(member.getDeclaringClass().getName());
    }

    public Logger get() {
      return Logger.getAnonymousLogger();
    }

    public String toString() {
      return "Provider<Logger>";
    }
  }

}
