/*
 * 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.core.linker;

import com.google.gwt.core.ext.LinkerContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.linker.CompilationResult;
import com.google.gwt.core.ext.linker.ConfigurationProperty;
import com.google.gwt.core.ext.linker.LinkerOrder;
import com.google.gwt.core.ext.linker.Shardable;
import com.google.gwt.core.ext.linker.StatementRanges;
import com.google.gwt.core.ext.linker.LinkerOrder.Order;
import com.google.gwt.core.ext.linker.impl.SelectionScriptLinker;
import com.google.gwt.dev.About;
import com.google.gwt.dev.util.DefaultTextOutput;
import com.google.gwt.dev.util.Util;

import java.util.SortedSet;

/**
 * Implements the canonical GWT bootstrap sequence that loads the GWT module in
 * a separate iframe.
 */
@LinkerOrder(Order.PRIMARY)
@Shardable
public class IFrameLinker extends SelectionScriptLinker {
  /**
   * This string is inserted between script chunks. It is made default access
   * for testing.
   */
  static final String SCRIPT_CHUNK_SEPARATOR = "--></script>\n<script><!--\n";

  /**
   * A configuration property indicating how large each script tag should be.
   */
  private static final String CHUNK_SIZE_PROPERTY = "iframe.linker.script.chunk.size";

  /**
   * A configuration property that can be used to have the linker load from
   * somewhere other than {@link #FRAGMENT_SUBDIR}.
   */
  private static final String PROP_FRAGMENT_SUBDIR_OVERRIDE = "iframe.linker.deferredjs.subdir";

  /**
   * Split a JavaScript string into multiple chunks, at statement boundaries.
   * Insert and end-script tag and a start-script tag in between each chunk.
   * This method is made default access for testing.
   * 
   * @param ranges Describes where the statements are located within the
   *          JavaScript code. If <code>null</code>, then return <code>js</code>
   *          unchanged.
   * @param js The JavaScript code to be split up.
   * @param charsPerChunk The number of characters to be put in each script tag
   */
  static String splitPrimaryJavaScript(StatementRanges ranges, String js,
      int charsPerChunk) {
    if (charsPerChunk < 0 || ranges == null) {
      return js;
    }

    StringBuilder sb = new StringBuilder();
    int bytesInCurrentTag = 0;

    for (int i = 0; i < ranges.numStatements(); i++) {
      int start = ranges.start(i);
      int end = ranges.end(i);
      int length = end - start;
      if (bytesInCurrentTag > 0 && bytesInCurrentTag + length > charsPerChunk) {
        if (lastChar(sb) != '\n') {
          sb.append('\n');
        }
        sb.append(SCRIPT_CHUNK_SEPARATOR);
        bytesInCurrentTag = 0;
      }
      if (bytesInCurrentTag > 0) {
        char lastChar = lastChar(sb);
        if (lastChar != '\n' && lastChar != ';' && lastChar != '}') {
          /*
           * Make sure this statement has a separator from the last one.
           */
          sb.append(";");
        }
      }
      sb.append(js, start, end);
      bytesInCurrentTag += length;
    }
    return sb.toString();
  }

  private static char lastChar(StringBuilder sb) {
    return sb.charAt(sb.length() - 1);
  }

  @Override
  public String getDescription() {
    return "Standard";
  }

  /*
   * This implementation divides the code of the initial fragment into multiple
   * script tags. These chunked script tags loads faster on Firefox even when
   * the data is cached. Additionally, having the script tags separated means
   * that the early ones can be evaluated before the later ones have finished
   * downloading. As a result of this parallelism, the overall time to get the
   * JavaScript downloaded and evaluated can lower.
   */
  @Override
  protected byte[] generatePrimaryFragment(TreeLogger logger,
      LinkerContext context, CompilationResult result, String[] js)
      throws UnableToCompleteException {
    StringBuffer b = new StringBuffer();
    b.append(getModulePrefix(logger, context, result.getStrongName(), js.length));
    b.append(splitPrimaryJavaScript(result.getStatementRanges()[0], js[0],
        charsPerChunk(context, logger)));
    b.append(getModuleSuffix(logger, context));
    return Util.getBytes(b.toString());
  }
  
  @Override
  protected String getCompilationExtension(TreeLogger logger,
      LinkerContext context) {
    return ".cache.html";
  }

  /**
   * Returns the subdirectory name to be used by getModulPrefix when requesting
   * a runAsync module. It is specified by
   * {@link #PROP_FRAGMENT_SUBDIR_OVERRIDE} and, aside from test cases, is
   * always {@link #FRAGMENT_SUBDIR}.
   */
  protected final String getFragmentSubdir(TreeLogger logger,
      LinkerContext context) throws UnableToCompleteException {
    String subdir = null;
    for (ConfigurationProperty prop : context.getConfigurationProperties()) {
      if (prop.getName().equals(PROP_FRAGMENT_SUBDIR_OVERRIDE)) {
        subdir = prop.getValues().get(0);
      }
    }

    if (subdir == null) {
      logger.log(TreeLogger.ERROR, "Could not find property "
          + PROP_FRAGMENT_SUBDIR_OVERRIDE);
      throw new UnableToCompleteException();
    }

    return subdir;
  }

  @Override
  protected String getHostedFilename() {
    return "hosted.html";
  }

  @Override
  protected String getModulePrefix(TreeLogger logger, LinkerContext context,
      String strongName) throws UnableToCompleteException {
    return getModulePrefix(logger, context, strongName, true);
  }

  @Override
  protected String getModulePrefix(TreeLogger logger, LinkerContext context,
      String strongName, int numFragments) throws UnableToCompleteException {
    return getModulePrefix(logger, context, strongName, numFragments > 1);
  }

  @Override
  protected String getModuleSuffix(TreeLogger logger, LinkerContext context) {
    DefaultTextOutput out = new DefaultTextOutput(context.isOutputCompact());

    out.print("$stats && $stats({moduleName:'" + context.getModuleName()
        + "',sessionId:$sessionId"
        + ",subSystem:'startup',evtGroup:'moduleStartup'"
        + ",millis:(new Date()).getTime(),type:'moduleEvalEnd'});");

    // Generate the call to tell the bootstrap code that we're ready to go.
    out.newlineOpt();
    out.print("if ($wnd." + context.getModuleFunctionName() + ") $wnd."
        + context.getModuleFunctionName() + ".onScriptLoad();");
    out.newline();
    out.print("--></script></body></html>");
    out.newlineOpt();

    return out.toString();
  }

  @Override
  protected String getSelectionScriptTemplate(TreeLogger logger, LinkerContext context) {
    return "com/google/gwt/core/linker/IFrameTemplate.js";
  }

  protected String modifyPrimaryJavaScript(String js) {
    return js;
  }

  /**
   * Extract via {@link #CHUNK_SIZE_PROPERTY} the number of characters to be
   * included in each script tag.
   */
  private int charsPerChunk(LinkerContext context, TreeLogger logger)
      throws UnableToCompleteException {
    SortedSet<ConfigurationProperty> configProps = context.getConfigurationProperties();
    for (ConfigurationProperty prop : configProps) {
      if (prop.getName().equals(CHUNK_SIZE_PROPERTY)) {
        return Integer.parseInt(prop.getValues().get(0));
      }
    }

    logger.log(TreeLogger.ERROR, "Unable to find configuration property "
        + CHUNK_SIZE_PROPERTY);
    throw new UnableToCompleteException();
  }

  /**
   * This is the real implementation of <code>getModulePrefix</code> for this
   * linker. The other versions forward to this one.
   */
  private String getModulePrefix(TreeLogger logger, LinkerContext context,
      String strongName, boolean supportRunAsync)
      throws UnableToCompleteException {
    DefaultTextOutput out = new DefaultTextOutput(context.isOutputCompact());
    out.print("<html>");
    out.newlineOpt();

    // Setup the well-known variables.
    out.print("<head><meta charset=\"UTF-8\" /><script>");
    out.newlineOpt();
    out.print("var $gwt_version = \"" + About.getGwtVersionNum() + "\";");
    out.newlineOpt();
    out.print("var $wnd = parent;");
    out.newlineOpt();
    out.print("var $doc = $wnd.document;");
    out.newlineOpt();
    out.print("var $moduleName, $moduleBase;");
    out.newlineOpt();
    out.print("var $strongName = '" + strongName + "';");
    out.newlineOpt();
    if (supportRunAsync) {
      out.print("function __gwtStartLoadingFragment(frag) {");
      out.indentIn();
      out.newlineOpt();
      out.print("  return $moduleBase + '" + getFragmentSubdir(logger, context)
          + "/'  + $strongName + '/' + frag + '" + FRAGMENT_EXTENSION + "';");
      out.indentOut();
      out.newlineOpt();
      out.print("};");
      out.newlineOpt();
      out.print("function __gwtInstallCode(code) {");
      /*
       * Use a script tag on all platforms, for simplicity. It would be cleaner
       * to use window.eval, but at the time of writing that only reliably works
       * on Firefox. It would also be cleaner to use window.execScript on
       * platforms that support it (IE and Chrome). However, trying this causes
       * IE 6 (and possibly others) to emit "error 80020101", apparently due to
       * something objectionable in the compiler's output JavaScript.
       */
      out.indentIn();
      out.newlineOpt();
      out.print("var head = document.getElementsByTagName('head').item(0);");
      out.newlineOpt();
      out.print("var script = document.createElement('script');");
      out.newlineOpt();
      out.print("script.type = 'text/javascript';");
      out.newlineOpt();
      out.print("script.text = code;");
      out.newlineOpt();
      out.print("head.appendChild(script);");
      out.indentOut();
      out.newlineOpt();
      out.print("};");
      out.newlineOpt();
    }
    out.print("var $stats = $wnd.__gwtStatsEvent ? function(a) {return $wnd.__gwtStatsEvent(a);} : null,");
    out.newlineOpt();
    out.print("$sessionId = $wnd.__gwtStatsSessionId ? $wnd.__gwtStatsSessionId : null;");
    out.newlineOpt();
    out.print("$stats && $stats({moduleName:'" + context.getModuleName()
        + "',sessionId:$sessionId"
        + ",subSystem:'startup',evtGroup:'moduleStartup'"
        + ",millis:(new Date()).getTime(),type:'moduleEvalStart'});");
    out.newlineOpt();
    out.print("</script></head>");
    out.newlineOpt();
    out.print("<body>");
    out.newlineOpt();

    // Begin a script block inside the body. It's commented out so that the
    // browser won't mistake strings containing "<script>" for actual script.
    out.print("<script><!--");
    out.newline();
    return out.toString();
  }

}
