/*
 * 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;

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.CompileTaskRunner.CompileTask;
import com.google.gwt.dev.cfg.ModuleDef;
import com.google.gwt.dev.cfg.ModuleDefLoader;
import com.google.gwt.dev.javac.UnitCache;
import com.google.gwt.dev.javac.UnitCacheSingleton;
import com.google.gwt.dev.jjs.PermutationResult;
import com.google.gwt.dev.js.JsNamespaceOption;
import com.google.gwt.dev.util.Memory;
import com.google.gwt.dev.util.PersistenceBackedObject;
import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.arg.ArgHandlerDeployDir;
import com.google.gwt.dev.util.arg.ArgHandlerExtraDir;
import com.google.gwt.dev.util.arg.ArgHandlerIncrementalCompile;
import com.google.gwt.dev.util.arg.ArgHandlerLocalWorkers;
import com.google.gwt.dev.util.arg.ArgHandlerSaveSourceOutput;
import com.google.gwt.dev.util.arg.ArgHandlerWarDir;
import com.google.gwt.dev.util.arg.ArgHandlerWorkDirOptional;
import com.google.gwt.dev.util.arg.OptionOptimize;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
import com.google.gwt.thirdparty.guava.common.collect.Sets;
import com.google.gwt.util.tools.Utility;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * The main executable entry point for the GWT Java to JavaScript compiler.
 */
public class Compiler {

  static class ArgProcessor extends PrecompileTaskArgProcessor {
    public ArgProcessor(CompilerOptions options) {
      super(options);

      registerHandler(new ArgHandlerLocalWorkers(options));

      // Override the ArgHandlerWorkDirRequired in the super class.
      registerHandler(new ArgHandlerWorkDirOptional(options));
      registerHandler(new ArgHandlerIncrementalCompile(options));

      registerHandler(new ArgHandlerWarDir(options));
      registerHandler(new ArgHandlerDeployDir(options));
      registerHandler(new ArgHandlerExtraDir(options));
      registerHandler(new ArgHandlerSaveSourceOutput(options));
    }

    @Override
    protected String getName() {
      return Compiler.class.getName();
    }
  }

  /**
   * Locates the unit cache dir relative to the war dir and returns a UnitCache instance.
   */
  public static UnitCache getOrCreateUnitCache(TreeLogger logger, CompilerOptions options) {
    File persistentUnitCacheDir = null;
    if (options.getWarDir() != null && options.getWarDir().isDirectory()) {
      persistentUnitCacheDir = new File(options.getWarDir(), "../");
    }
    // TODO: returns the same UnitCache even if the passed directory changes. Make this less
    // surprising.
    return UnitCacheSingleton.get(logger, null, persistentUnitCacheDir, options);
  }

  public static void main(String[] args) {
    Memory.initialize();
    if (System.getProperty("gwt.jjs.dumpAst") != null) {
      System.out.println("Will dump AST to: "
          + System.getProperty("gwt.jjs.dumpAst"));
    }

    SpeedTracerLogger.init();

    /*
     * NOTE: main always exits with a call to System.exit to terminate any
     * non-daemon threads that were started in Generators. Typically, this is to
     * shutdown AWT related threads, since the contract for their termination is
     * still implementation-dependent.
     */
    final CompilerOptions options = new CompilerOptionsImpl();
    if (new ArgProcessor(options).processArgs(args)) {
      CompileTask task = new CompileTask() {
        @Override
        public boolean run(TreeLogger logger) throws UnableToCompleteException {
          return Compiler.compile(logger, options);
        }
      };
      if (CompileTaskRunner.runWithAppropriateLogger(options, task)) {
        // Exit w/ success code.
        System.exit(0);
      }
    }
    // Exit w/ non-success code.
    System.exit(1);
  }

  public static boolean compile(
      TreeLogger logger, CompilerOptions compilerOptions)
      throws UnableToCompleteException {
    List<ModuleDef> moduleDefs = new ArrayList<>();
    for (String moduleName : compilerOptions.getModuleNames()) {
      moduleDefs.add(ModuleDefLoader.loadFromClassPath(logger, moduleName, true));
    }

    boolean result = true;
    for (ModuleDef moduleDef : moduleDefs) {
      result &= compile(logger, compilerOptions, moduleDef);
    }
    return result;
  }

  public static boolean compile(
      TreeLogger logger, CompilerOptions compilerOptions, ModuleDef moduleDef)
      throws UnableToCompleteException {
    MinimalRebuildCache minimalRebuildCache = compilerOptions.isIncrementalCompileEnabled()
        ? new MinimalRebuildCache()
        : new NullRebuildCache();
    return compile(logger, compilerOptions, minimalRebuildCache, moduleDef);
  }

  public static boolean compile(
      TreeLogger logger,
      CompilerOptions compilerOptions,
      MinimalRebuildCache minimalRebuildCache,
      ModuleDef moduleDef)
      throws UnableToCompleteException {

    CompilerOptionsImpl  options = new CompilerOptionsImpl(compilerOptions);
    boolean tempWorkDir = false;
    try {
      if (options.getWorkDir() == null) {
        options.setWorkDir(Utility.makeTemporaryDirectory(null, "gwtc"));
        tempWorkDir = true;
      }
      if ((options.isSoycEnabled() || options.isJsonSoycEnabled())
          && options.getExtraDir() == null) {
        options.setExtraDir(new File("extras"));
      }
      if (options.isIncrementalCompileEnabled()) {
        // Disable options that disrupt contiguous output JS source per class.
        options.setClusterSimilarFunctions(false);
        options.setOptimizationLevel(OptionOptimize.OPTIMIZE_LEVEL_DRAFT);
        options.setRunAsyncEnabled(false);

        // Disable options that disrupt reference consistency across multiple compiles.
        // TODO(stalcup): preserve Namespace state in MinimalRebuildCache across compiles.
        options.setNamespace(JsNamespaceOption.NONE);
      }

      CompilerContext compilerContext =
          new CompilerContext.Builder()
              .options(options)
              .minimalRebuildCache(minimalRebuildCache)
              .unitCache(getOrCreateUnitCache(logger, options))
              .module(moduleDef)
              .build();
      String moduleName = moduleDef.getCanonicalName();
      if (options.isValidateOnly()) {
        if (!Precompile.validate(logger, compilerContext)) {
          return false;
        }
      } else {
        long beforeCompileMs = System.currentTimeMillis();
        TreeLogger branch = logger.branch(TreeLogger.INFO,
            "Compiling module " + moduleName);

        Precompilation precompilation = Precompile.precompile(branch, compilerContext);
        if (precompilation == null) {
          return false;
        }
        // TODO: move to precompile() after params are refactored
        if (!options.shouldSaveSource()) {
          precompilation.removeSourceArtifacts(branch);
        }

        Event compilePermutationsEvent =
            SpeedTracerLogger.start(CompilerEventType.COMPILE_PERMUTATIONS);
        Permutation[] allPerms = precompilation.getPermutations();
        List<PersistenceBackedObject<PermutationResult>> resultFiles =
            CompilePerms.makeResultFiles(
                options.getCompilerWorkDir(moduleName), allPerms, options);
        CompilePerms.compile(branch, compilerContext, precompilation, allPerms,
            options.getLocalWorkers(), resultFiles);
        compilePermutationsEvent.end();

        ArtifactSet generatedArtifacts = precompilation.getGeneratedArtifacts();
        PrecompileTaskOptions precompileOptions = precompilation.getUnifiedAst().getOptions();

        precompilation = null; // No longer needed, so save the memory
        long afterCompileMs = System.currentTimeMillis();
        double compileSeconds = (afterCompileMs - beforeCompileMs) / 1000d;
        branch.log(TreeLogger.INFO,
            String.format("Compilation succeeded -- %.3fs", compileSeconds));

        long beforeLinkMs = System.currentTimeMillis();
        Event linkEvent = SpeedTracerLogger.start(CompilerEventType.LINK);
        File absPath = new File(options.getWarDir(), moduleDef.getName());
        absPath = absPath.getAbsoluteFile();

        String logMessage = "Linking into " + absPath;
        if (options.getExtraDir() != null) {
          File absExtrasPath = new File(options.getExtraDir(),
              moduleDef.getName());
          absExtrasPath = absExtrasPath.getAbsoluteFile();
          logMessage += "; Writing extras to " + absExtrasPath;
        }
        Link.link(logger.branch(TreeLogger.TRACE, logMessage), moduleDef,
            moduleDef.getPublicResourceOracle(), generatedArtifacts, allPerms, resultFiles,
            Sets.<PermutationResult>newHashSet(), precompileOptions, options);
        linkEvent.end();
        long afterLinkMs = System.currentTimeMillis();
        double linkSeconds = (afterLinkMs - beforeLinkMs) / 1000d;
        branch.log(TreeLogger.INFO, String.format("Linking succeeded -- %.3fs", linkSeconds));
      }

    } catch (IOException e) {
      logger.log(TreeLogger.ERROR, "Unable to create compiler work directory",
          e);
      return false;
    } finally {
      if (tempWorkDir) {
        Util.recursiveDelete(options.getWorkDir(), false);
      }
    }
    return true;
  }
}
