/*
 * Copyright 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.gwt.dev.shell;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.dev.CompilerContext;
import com.google.gwt.dev.PrecompileTaskOptionsImpl;
import com.google.gwt.dev.RebindCache;
import com.google.gwt.dev.cfg.ModuleDef;
import com.google.gwt.dev.cfg.Rules;
import com.google.gwt.dev.javac.CompilationState;
import com.google.gwt.dev.javac.StandardGeneratorContext;
import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;

import java.io.File;

/**
 * Provides an environment for a {@link com.google.gwt.dev.shell.ModuleSpace}
 * that works appropriately for the development shell.
 */
public class ShellModuleSpaceHost implements ModuleSpaceHost {

  // TODO(jat): hack to try and serialize rebinds
  private static final Object rebindLock = new Object[0];

  protected final CompilationState compilationState;

  protected final File genDir;

  private final ArtifactAcceptor artifactAcceptor;

  private CompilingClassLoader classLoader;

  private final TreeLogger logger;

  private final ModuleDef module;

  private StandardRebindOracle rebindOracle;

  private ModuleSpace space;

  private RebindCache rebindCache;

  /**
   * @param module the module associated with the hosted module space
   */
  public ShellModuleSpaceHost(TreeLogger logger,
      CompilationState compilationState, ModuleDef module, File genDir,
      ArtifactAcceptor artifactAcceptor, RebindCache rebindCache) {
    this.logger = logger;
    this.compilationState = compilationState;
    this.module = module;
    this.genDir = genDir;
    this.artifactAcceptor = artifactAcceptor;
    this.rebindCache = rebindCache;
  }

  public CompilingClassLoader getClassLoader() {
    checkForModuleSpace();
    return classLoader;
  }

  public String[] getEntryPointTypeNames() {
    checkForModuleSpace();
    return module.getEntryPointTypeNames();
  }

  public TreeLogger getLogger() {
    return logger;
  }

  /**
   * Invalidates the given source type name, so the next rebind request will
   * generate a type again.
   */
  public void invalidateRebind(String sourceTypeName) {
    checkForModuleSpace();
    rebindOracle.invalidateRebind(sourceTypeName);
  }

  public void onModuleReady(ModuleSpace readySpace)
      throws UnableToCompleteException {
    this.space = readySpace;

    Event moduleSpaceHostReadyEvent = SpeedTracerLogger.start(DevModeEventType.MODULE_SPACE_HOST_READY);
    try {
      // Establish an environment for JavaScript property providers to run.
      //
      ModuleSpacePropertyOracle propOracle = new ModuleSpacePropertyOracle(
          module.getProperties(), module.getActiveLinkerNames(), readySpace);

      // Set up the rebind oracle for the module.
      // It has to wait until now because we need to inject javascript.
      //
      Rules rules = module.getRules();
      PrecompileTaskOptionsImpl options = new PrecompileTaskOptionsImpl();
      options.setGenDir(genDir);
      CompilerContext compilerContext =
          new CompilerContext.Builder().module(module).options(options).build();
      StandardGeneratorContext genCtx =
          new StandardGeneratorContext(compilerContext, compilationState, new ArtifactSet(), false);

      // Only enable generator result caching if we have a valid rebindCache
      genCtx.setGeneratorResultCachingEnabled((rebindCache != null));

      rebindOracle = new StandardRebindOracle(propOracle, rules, genCtx);
      rebindOracle.setRebindCache(rebindCache);

      // Create a completely isolated class loader which owns all classes
      // associated with a particular module. This effectively builds a
      // separate 'domain' for each running module, so that they all behave as
      // though they are running separately. This allows the shell to run
      // multiple modules, both in succession and simultaneously, without getting
      // confused.
      //
      // Note that the compiling class loader has no parent. This keeps it from
      // accidentally 'escaping' its domain and loading classes from the system
      // class loader (the one that loaded the shell itself).
      //
      classLoader = new CompilingClassLoader(logger, compilationState, readySpace);
    } finally {
      moduleSpaceHostReadyEvent.end();
    }
  }

  public String rebind(TreeLogger logger, String sourceTypeName)
      throws UnableToCompleteException {
    synchronized (rebindLock) {
      checkForModuleSpace();
      return rebindOracle.rebind(logger, sourceTypeName, new ArtifactAcceptor() {
        public void accept(TreeLogger logger, ArtifactSet newlyGeneratedArtifacts)
        throws UnableToCompleteException {
          artifactAcceptor.accept(logger, newlyGeneratedArtifacts);
        }
      });
    }
  }

  private void checkForModuleSpace() {
    if (space == null) {
      throw new IllegalStateException("Module initialization error");
    }
  }
}
