/*
 * Copyright 2011 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.js;

import com.google.gwt.dev.jjs.JsOutputOption;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.impl.codesplitter.FragmentPartitioningResult;
import com.google.gwt.dev.js.ast.JsProgram;
import com.google.gwt.dev.js.ast.JsProgramFragment;
import com.google.gwt.thirdparty.guava.common.base.Preconditions;
import com.google.gwt.thirdparty.guava.common.base.Throwables;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableList;
import com.google.gwt.thirdparty.guava.common.collect.Lists;
import com.google.gwt.thirdparty.guava.common.collect.Maps;
import com.google.gwt.thirdparty.guava.common.collect.Sets;
import com.google.gwt.thirdparty.guava.common.io.ByteStreams;
import com.google.gwt.thirdparty.javascript.jscomp.CheckLevel;
import com.google.gwt.thirdparty.javascript.jscomp.Compiler;
import com.google.gwt.thirdparty.javascript.jscomp.CompilerInput;
import com.google.gwt.thirdparty.javascript.jscomp.CompilerOptions;
import com.google.gwt.thirdparty.javascript.jscomp.CompilerOptions.Reach;
import com.google.gwt.thirdparty.javascript.jscomp.DiagnosticGroups;
import com.google.gwt.thirdparty.javascript.jscomp.JSError;
import com.google.gwt.thirdparty.javascript.jscomp.JSModule;
import com.google.gwt.thirdparty.javascript.jscomp.JSSourceFile;
import com.google.gwt.thirdparty.javascript.jscomp.PropertyRenamingPolicy;
import com.google.gwt.thirdparty.javascript.jscomp.Result;
import com.google.gwt.thirdparty.javascript.jscomp.SourceAst;
import com.google.gwt.thirdparty.javascript.jscomp.VariableMap;
import com.google.gwt.thirdparty.javascript.jscomp.VariableRenamingPolicy;
import com.google.gwt.thirdparty.javascript.jscomp.WarningLevel;
import com.google.gwt.thirdparty.javascript.rhino.InputId;
import com.google.gwt.thirdparty.javascript.rhino.Node;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * A class that represents an single invocation of the Closure Compiler.
 */
public class ClosureJsRunner {
  // The externs expected in externs.zip, in sorted order.
  private static final List<String> DEFAULT_EXTERNS_NAMES = ImmutableList.of(
      // JS externs
      "es3.js",
      "es5.js",

      // Event APIs
      "w3c_event.js", "w3c_event3.js", "w3c_device_sensor_event.js",
      "gecko_event.js",
      "ie_event.js",
      "webkit_event.js",

      // DOM apis
      "w3c_dom1.js", "w3c_dom2.js", "w3c_dom3.js",
      "gecko_dom.js",
      "ie_dom.js",
      "webkit_dom.js",

      // CSS apis
      "w3c_css.js",
      "gecko_css.js",
      "ie_css.js",
      "webkit_css.js",

      // Top-level namespaces
      "chrome.js", "google.js",

      "deprecated.js", "fileapi.js", "flash.js", "gears_symbols.js", "gears_types.js",
      "gecko_xml.js", "html5.js", "ie_vml.js", "iphone.js", "webstorage.js", "w3c_anim_timing.js",
      "w3c_css3d.js", "w3c_elementtraversal.js", "w3c_geolocation.js", "w3c_indexeddb.js",
      "w3c_navigation_timing.js", "w3c_range.js", "w3c_selectors.js", "w3c_xml.js", "window.js",
      "webkit_notifications.js", "webgl.js");

  /**
   * @return a mutable list
   * @throws IOException
   */
  public static List<JSSourceFile> getDefaultExterns() throws IOException {
    Class<ClosureJsRunner> clazz = ClosureJsRunner.class;
    InputStream input = clazz.getResourceAsStream("/com/google/javascript/jscomp/externs.zip");
    if (input == null) {
      /*
       * HACK - the open source version of the closure compiler maps the resource into a different
       * location.
       */
      input = clazz.getResourceAsStream("/externs.zip");
    }
    ZipInputStream zip = new ZipInputStream(input);
    Map<String, JSSourceFile> externsMap = Maps.newHashMap();
    for (ZipEntry entry = null; (entry = zip.getNextEntry()) != null;) {
      BufferedInputStream entryStream =
          new BufferedInputStream(ByteStreams.limit(zip, entry.getSize()));
      externsMap.put(entry.getName(), JSSourceFile.fromInputStream(
      // Give the files an odd prefix, so that they do not conflict
      // with the user's files.
          "externs.zip//" + entry.getName(), entryStream));
    }

    Preconditions.checkState(externsMap.keySet().equals(Sets.newHashSet(DEFAULT_EXTERNS_NAMES)),
        "Externs zip must match our hard-coded list of externs.");

    // Order matters, so the resources must be added to the result list
    // in the expected order.
    List<JSSourceFile> externs = Lists.newArrayList();
    for (String key : DEFAULT_EXTERNS_NAMES) {
      externs.add(externsMap.get(key));
    }

    return externs;
  }

  /**
   * The instance of the Closure Compiler used for the compile.
   */
  private Compiler compiler = null;

  /**
   * The set of external properties discovered in the provided AST.
   */
  private Set<String> externalProps = Sets.newHashSet();

  /**
   * The set of external global variables discovered in the provided AST.
   */
  private Set<String> externalVars = Sets.newHashSet();

  /**
   * The set of internal global variables discovered in the provided AST.
   */
  private Set<String> globalVars = Sets.newHashSet();

  /**
   * Whether AST validation should be performed on the generated
   * Closure Compiler AST.
   */
  private final boolean validate = true;

  /**
   * A map of GWT fragment numbers to Closure module indexes.
   */
  private int[] closureModuleSequenceMap;

  /**
   * The number of non-exclusive fragments that are part of the load sequence
   * (including the main and leftovers).
   */
  private int loadModulesCount;

  public ClosureJsRunner() {
  }

  public void compile(JProgram jprogram, JsProgram program, String[] js,
      JsOutputOption jsOutputOption) {
    CompilerOptions options;
    try {
      options = getClosureCompilerOptions(jsOutputOption);
    } catch (ParseException e) {
      throw new RuntimeException("Error setting closure compiler options", e);
    }
    // Turn off Closure Compiler logging
    Logger.getLogger("com.google.gwt.thirdparty.javascript.jscomp").setLevel(Level.OFF);

    // Create a fresh compiler instance.
    compiler = new Compiler();

    // Translate the ASTs and build the modules
    computeFragmentMap(jprogram, program);
    List<JSModule> modules = createClosureModules(program);

    // Build the externs based on what we discovered building the modules.
    List<JSSourceFile> externs = getClosureCompilerExterns();

    Result result = compiler.compileModules(externs, modules, options);
    if (result.success) {
      int fragments = program.getFragmentCount();
      for (int i = 0; i < fragments; i++) {
        int module = mapFragmentIndexToModuleIndex(i);
        js[i] = compiler.toSource(modules.get(module));
      }
    } else {
      for (JSError error : result.errors) {
        System.err.println("error optimizing:" + error.toString());
        throw new RuntimeException(error.description);
      }
    }
  }

  protected List<JSSourceFile> getDefaultExternsList() {
    List<JSSourceFile> defaultExterns;
    try {
      defaultExterns = getDefaultExterns();
      return defaultExterns;
    } catch (IOException e) {
      throw Throwables.propagate(e);
    }
  }

  private void computeFragmentMap(JProgram jprogram, JsProgram jsProgram) {
    int fragments = jsProgram.getFragmentCount();
    List<Integer> initSeq = jprogram.getInitialFragmentIdSequence();
    FragmentPartitioningResult partitionResult = jprogram.getFragmentPartitioningResult();

    //
    // The fragments are expected in a specific order:
    // init, split-1, split-2, ...,
    // where the leftovers are dependent on the init module
    // and the split modules are dependent on the leftovers
    //
    // However, Closure Compiler modules must be in dependency order
    //

    assert closureModuleSequenceMap == null;
    closureModuleSequenceMap = new int[fragments];
    for (int i = 0; i < fragments; i++) {
      closureModuleSequenceMap[i] = -1;
    }

    int module = 0;
    // The initial fragments is always first.
    closureModuleSequenceMap[0] = module++;

    // Then come the specified load order sequence
    for (int i = 0; i < initSeq.size(); i++) {
      int initSeqNum = initSeq.get(i);
      if (partitionResult != null) {
        initSeqNum = partitionResult.getFragmentForRunAsync(initSeqNum);
      }
      closureModuleSequenceMap[initSeqNum] = module++;
    }

    // Then the leftovers fragments:
    if (fragments > 1) {
      int leftoverIndex = fragments - 1;
      if (partitionResult != null) {
        leftoverIndex = partitionResult.getLeftoverFragmentId();
      }
      closureModuleSequenceMap[leftoverIndex] = module++;
    }

    // Finally, the exclusive fragments.
    // The order of the remaining fragments doesn't matter.
    for (int i = 0; i < fragments; i++) {
      if (closureModuleSequenceMap[i] == -1) {
        closureModuleSequenceMap[i] = module++;
      }
    }
    loadModulesCount = 1 + initSeq.size() + 1; // main + init sequence + leftovers
  }

  private CompilerInput createClosureJsAst(JsProgram program, JsProgramFragment fragment,
      String source) {
    String inputName = source;
    InputId inputId = new InputId(inputName);
    ClosureJsAstTranslator translator = new ClosureJsAstTranslator(validate, program);
    Node root = translator.translate(fragment, inputId, source);
    globalVars.addAll(translator.getGlobalVariableNames());
    externalProps.addAll(translator.getExternalPropertyReferences());
    externalVars.addAll(translator.getExternalVariableReferences());
    SourceAst sourceAst = new ClosureJsAst(inputId, root);
    CompilerInput input = new CompilerInput(sourceAst, false);
    return input;
  }

  private JSModule createClosureModule(JsProgram program, JsProgramFragment fragment, String source) {
    JSModule module = new JSModule(source);
    module.add(createClosureJsAst(program, fragment, source));
    return module;
  }

  private List<JSModule> createClosureModules(JsProgram program) {
    int fragments = program.getFragmentCount();
    JSModule[] modules = new JSModule[fragments];

    for (int i = 0; i < fragments; i++) {
      modules[mapFragmentIndexToModuleIndex(i)] =
          createClosureModule(program, program.getFragment(i), "module" + i);
    }
    if (fragments > 1) {
      //
      // The fragments are expected in a specific order:
      // init, split-1, split-2, ...,
      // where the leftovers are dependent on the init module
      // and the split modules are dependent on the leftovers
      for (int i = 1; i < loadModulesCount; i++) {
        modules[i].addDependency(modules[i - 1]);
      }

      JSModule leftovers = modules[loadModulesCount - 1];
      for (int i = loadModulesCount; i < modules.length; i++) {
        Preconditions.checkNotNull(modules[i], "Module: ", i);
        modules[i].addDependency(leftovers);
      }
    }
    modules[0].add(JSSourceFile.fromCode("hack", "window['gwtOnLoad'] = gwtOnLoad;\n"));

    return Arrays.asList(modules);
  }

  private List<JSSourceFile> getClosureCompilerExterns() {
    List<JSSourceFile> externs = getDefaultExternsList();
    externs.add(JSSourceFile.fromCode("gwt_externs",

    "var gwtOnLoad;\n"
        + "var $entry;\n"
        + "    var $gwt_version;\n"
        + "    var $wnd;\n"
        + "    var $doc;\n"
        + "    var $moduleName\n"
        + "    var $moduleBase;\n"
        + "    var $gwt\n"
        + "    var $strongName;\n"
        + "    var $stats;\n"
        + "    var $sessionId;\n"
        + "    window.prototype.__gwtStatsEvent;\n"
        + "    window.prototype.__gwtStatsSessionId;\n"
        + "    window.prototype.moduleName;\n"
        + "    window.prototype.sessionId;\n"
        + "    window.prototype.subSystem;\n"
        + "    window.prototype.evtGroup;\n"
        + "    window.prototype.millis;\n"
        + "    window.prototype.type;\n"
        + "    window.prototype.$h;\n"
        + "\n"));

    // Generate externs
    String generatedExterns = "var gwt_externs;\n";
    for (String prop : this.externalProps) {
      generatedExterns += "gwt_externs." + prop + ";\n";
    }

    for (String var : this.externalVars) {
      generatedExterns += "var " + var + ";\n";
    }

    externs.add(JSSourceFile.fromCode("gwt_generated_externs", generatedExterns));

    return externs;
  }

  private CompilerOptions getClosureCompilerOptions(JsOutputOption jsOutputOption)
      throws ParseException {
    CompilerOptions options = new CompilerOptions();
    WarningLevel.QUIET.setOptionsForWarningLevel(options);

    // Basically, use CompilationLevel.ADVANCED_OPTIMIZATIONS:

    // Build an identity map of variable names to prevent GWT names from
    // being renamed while allowing new global variables to be renamed.
    HashMap<String, String> varNames = new HashMap<String, String>();
    for (String var : globalVars) {
      varNames.put(var, var);
    }
    options.setInputVariableMapSerialized(VariableMap.fromMap(varNames).toBytes());
    if (jsOutputOption == JsOutputOption.OBFUSCATED) {
      options.setRenamingPolicy(VariableRenamingPolicy.ALL, PropertyRenamingPolicy.OFF);
      options.setPrettyPrint(false);
      // This can help debug renaming policy changes.
      // options.generatePseudoNames = true;
    } else {
      options.setRenamingPolicy(VariableRenamingPolicy.OFF, PropertyRenamingPolicy.OFF);
      options.setPrettyPrint(true);
    }

    // All the safe optimizations.
    options.setClosurePass(true);
    options.setFoldConstants(true);
    options.setCoalesceVariableNames(true);
    options.setDeadAssignmentElimination(true);
    options.setExtractPrototypeMemberDeclarations(true);
    options.setCollapseVariableDeclarations(true);
    options.setConvertToDottedProperties(true);
    options.setRewriteFunctionExpressions(true);
    options.setLabelRenaming(true);
    options.setRemoveDeadCode(true);
    options.setOptimizeArgumentsArray(true);
    options.setCollapseObjectLiterals(true);
    options.setShadowVariables(true);

    // All the advance optimizations.
    options.setReserveRawExports(true);
    options.setRemoveUnusedPrototypeProperties(true);
    options.setCollapseAnonymousFunctions(true);
    options.setSmartNameRemoval(true); // ?
    options.setInlineConstantVars(true);
    options.setInlineFunctions(Reach.ALL);
    options.setInlineGetters(true);
    options.setInlineVariables(Reach.ALL);
    options.setFlowSensitiveInlineVariables(true);
    options.setComputeFunctionSideEffects(true);
    // Remove unused vars also removes unused functions.
    options.setRemoveUnusedVariable(Reach.ALL);
    options.setOptimizeParameters(true);
    options.setOptimizeReturns(true);
    options.setOptimizeCalls(true);

    // Maybe turn these off as well
    options.setCollapseProperties(true); // ?
    options.setCrossModuleCodeMotion(true); // ?
    options.setCrossModuleMethodMotion(true); // ?
    options.setDevirtualizePrototypeMethods(true); // ?

    // Advanced optimization, disabled
    options.setRemoveClosureAsserts(false);
    options.setAliasKeywords(false);
    options.setRemoveUnusedPrototypePropertiesInExterns(false);
    options.setCheckGlobalThisLevel(CheckLevel.OFF);
    options.setRewriteFunctionExpressions(false); // Performance hit

    // Kindly tell the user that they have JsDocs that we don't understand.
    options.setWarningLevel(DiagnosticGroups.NON_STANDARD_JSDOC, CheckLevel.OFF);

    return options;
  }

  private int mapFragmentIndexToModuleIndex(int index) {
    assert closureModuleSequenceMap.length > index;
    return closureModuleSequenceMap[index];
  }
}
