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

import com.google.gwt.core.ext.linker.CompilationMetricsArtifact;
import com.google.gwt.core.ext.linker.ModuleMetricsArtifact;
import com.google.gwt.core.ext.linker.PrecompilationMetricsArtifact;
import com.google.gwt.core.ext.soyc.impl.SizeMapRecorder;
import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.collect.Lists;
import com.google.gwt.dev.util.collect.Sets;
import com.google.gwt.soyc.io.OutputDirectory;
import com.google.gwt.thirdparty.guava.common.base.Joiner;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * A utility to make all the HTML files for one permutation.
 */
public class MakeTopLevelHtmlForPerm {
  /**
   * A dependency linker for the initial code download. It links to the
   * dependencies for the initial download.
   */
  public class DependencyLinkerForInitialCode implements DependencyLinker {
    @Override
    public String dependencyLinkForClass(String className) {
      String packageName = globalInformation.getClassToPackage().get(className);
      assert packageName != null;
      return dependenciesFileName("initial") + "#" + className;
    }
  }

  /**
   * A dependency linker for the leftovers fragment. It links to leftovers
   * status pages.
   */
  public class DependencyLinkerForLeftoversFragment implements DependencyLinker {
    @Override
    public String dependencyLinkForClass(String className) {
      return leftoversStatusFileName() + "#"
          + hashedFilenameFragment(className);
    }
  }

  /**
   * A dependency linker for the total program breakdown. It links to a split
   * status page.
   *
   */
  public class DependencyLinkerForTotalBreakdown implements DependencyLinker {
    @Override
    public String dependencyLinkForClass(String className) {
      return splitStatusFileName() + "#" + hashedFilenameFragment(className);
    }
  }

  /**
   * A dependency linker that never links to anything.
   */
  public static class NullDependencyLinker implements DependencyLinker {
    @Override
    public String dependencyLinkForClass(String className) {
      return null;
    }
  }

  interface DependencyLinker {
    String dependencyLinkForClass(String className);
  }

  /**
   * Use this class to intern strings to save space in the generated HTML. After
   * populating the map, call getJs to create a JS array of all possible methods
   * in this report.
   */
  @SuppressWarnings("serial")
  private class HtmlInterner {
    // Hashes the interned string to the number of times this string is referenced.
    Map<String, Integer> builder = new HashMap<String, Integer>();
    // Hashes the interned string to its position in the final array of interned strings.
    // Populated after the call to {@link #freeze()}
    Map<String, Integer> frozen = null;

    /**
     * Call this method after all calls to {@link #intern(String)} are complete.
     * This routine then re-orders the interned calls in order of the number of
     * times each string was referenced by intern() so that lower numbered index
     * values represent more frequently referenced strings.
     */
    public void freeze() {
      final int maxDigits = 9;
      assert (frozen == null);
      assert (builder.size() < Math.pow(10, maxDigits));

      // order the interned values with the most referenced first.
      String[] temp = new String[builder.size()];
      int index = 0;
      for (String key : builder.keySet()) {
        temp[index++] = key.format("%0" + maxDigits + "d%s", builder.get(key), key);
      }
      builder = null;
      Arrays.sort(temp);

      // strip off the numeric prefix on the key to build the frozen hash table
      index = 0;
      frozen = new LinkedHashMap<String, Integer>();
      for (int i = temp.length - 1; i >= 0; i--) {
        frozen.put(temp[i].substring(maxDigits), index++);
      }
    }

    /**
     * Stores a string for later interning. Keeps track of the number of times a
     * particular string is interned which will be used by {@link #freeze()} to
     * place the most frequently used strings at the beginning of the
     * dictionary. After a call to {@link #freeze()}, it is no longer valid to
     * call this method.
     *
     * @param key string to be added to the intern dictionary.
     */
    public void intern(String key) {
      if (builder == null) {
        throw new RuntimeException("freeze() already called.");
      }
      if (!builder.containsKey(key)) {
        builder.put(key, 1);
      } else {
        int value = builder.get(key) + 1;
        builder.put(key, value);
      }
    }

    /**
     * Displays a link for a split point that contains this code.
     */
    public void printHasCodeInSplitPoint(PrintWriter outFile, String className,
        int sp) {
      outFile.print("h(" + frozen.get(getPackageSubstring(className)) + ","
          + frozen.get(getClassSubstring(className)) + "," + sp + ");");
    }

    /**
     * Non specific message that there is code in an initial fragment.
     */
    public void printHasInitialFragment(PrintWriter outFile) {
      outFile.print("f();");
    }

    /**
     * Displays a link for code in an initial fragment.
     */
    public void printHasInitialFragment(PrintWriter outFile, String className) {
      String packageName = getPackageSubstring(className);
      outFile.print("g(" + frozen.get(packageName) + ","
          + frozen.get(getClassSubstring(className)) + ","
          + frozen.get(hashedFilenameFragment(packageName)) + ");");
    }

    public void printSomeCodeLeftover(PrintWriter outFile) {
      outFile.print("i();");
    }

    /**
     * Prints an h3 element with the class name and an anchor.
     */
    private void printClassHeader(PrintWriter outFile, String className) {
      outFile.print("e(" + frozen.get(getPackageSubstring(className)) + ","
          + frozen.get(getClassSubstring(className)) + ",'"
          + hashedFilenameFragment(className) + "');");
    }

    /**
     * Print out a single class dependency stack in the methodDependencies
     * report.
     */
    private void printDependency(PrintWriter outFile,
        Map<String, String> dependencies, String method, String depMethod) {
      String nameArray = "[" + frozen.get(getPackageSubstring(method)) + ","
          + frozen.get(getClassSubstring(method)) + ","
          + frozen.get(getMethodSubstring(method)) + "]";
      outFile.print("b(" + nameArray + ",");
      outFile.print("[");
      while (depMethod != null) {
        String nextDep = dependencies.get(depMethod);
        // The bottom of the stack frame is not interesting.
        if (nextDep != null) {
          String packageString = getPackageSubstring(depMethod);
          String classString = getClassSubstring(depMethod);
          String methodString = getMethodSubstring(depMethod);
          outFile.print("[" + frozen.get(packageString) + ","
              + frozen.get(classString) + "," + frozen.get(methodString) + "]");
        }
        depMethod = nextDep;
        if (nextDep != null && dependencies.get(nextDep) != null) {
          outFile.print(",");
        }
      }
      outFile.print("]);");
    }

    /**
     * Prints out a class header for the methodDependendies report.
     */
    private void printDependencyClassHeader(PrintWriter outFile,
        String className) {
      outFile.print("a(" + frozen.get(getPackageSubstring(className)) + ","
          + frozen.get(getClassSubstring(className)) + ");");
    }

    /**
     * Prints a JavaScript snippet that includes the dictionary of interned
     * strings and methods to use interned strings to create lines in the
     * report.
     *
     * Call this method after invoking {@link #freeze()}.
     *
     * @param outFile open file to write the data to.
     */
    private void printInternedDataAsJs(PrintWriter outFile) {
      if (frozen == null) {
        throw new RuntimeException("freeze() not called.");
      }
      outFile.println("  var internedStrings = [");
      for (String key : frozen.keySet()) {
        outFile.print("\"" + key + "\",");
      }
      outFile.println("];");

      // array of split point descriptions
      outFile.println("  var spl = [");
      for (int fragment = 1; fragment <= globalInformation.getNumFragments(); fragment++) {
        final List<String> fragmentDescriptors = globalInformation.getFragmentDescriptors(fragment);
        String[] escapedFragmentDescriptors =
            new String[fragmentDescriptors.size()];
        for (int i = 0; i < fragmentDescriptors.size(); i++) {
          escapedFragmentDescriptors[i] =
              escapeJSString(fragmentDescriptors.get(i));
        }
        outFile.println("        '" + Joiner.on(",").join(escapedFragmentDescriptors) + "',");
      }
      outFile.println("  ];");
      
      // object/dictionary containing method sizes
      outFile.println("  var methodSizes = {");
      for (SizeBreakdown breakdown : globalInformation.allSizeBreakdowns()) {
        for (Entry<String, Integer> methodEntry : breakdown.methodToSize.entrySet()) {
          String methodSignature = methodEntry.getKey();
          String method = methodSignature.substring(0, methodSignature.indexOf("("));
          outFile.println("    \"" + method + "\" : " + methodEntry.getValue() + ",");
        }
      }
      outFile.println("};");
      
      // dropdown button image srcs
      outFile.println("  var images = {");
      outFile.println("    \"closed\" : \"images/play-g16.png\",");
      outFile.println("    \"open\" : \"images/play-g16-down.png\",");
      outFile.println("  };");

      // TODO(zundel): Most of this below is just inserting a fixed string into the code. It would
      // be easier to read and maintain if we could store the fixed part in a flat file. Use some
      // kind of HTML template?

      // function to print a class header in the methodDependencies report
      // see printDependencyClassHeader()
      outFile.println("  function a(packageRef, classRef) {");
      outFile.println("    var className = internedStrings[packageRef] + \".\" + "
          + "internedStrings[classRef];");
      outFile.println("    document.write(\"<div class='main'>\");");
      outFile.println("    document.write(\"<table class='soyc-table'>\");");
      outFile.println("    document.write(\"<thead>\");");
      outFile.println("    document.write(\"<th><a class='soyc-class-name' "
          + "name='\" + className + \"'>"
          + "Class: \" + className + \"</a></th>\");");
      outFile.println("    document.write(\"<th class='soyc-numerical-col-header'>Size "
          + "<span class='soyc-th-units'>(bytes)</span></th>\");");
      outFile.println("    document.write(\"</thead>\");");
      outFile.println("  }");
      
      outFile.println("  function swapShowHide(elementName) {");
      outFile.println("    hp = document.getElementById(elementName);");
      outFile.println("    arrow = document.getElementById(\"dropdown-\" + elementName);");
      outFile.println("    if (hp.style.display !== \"none\" && hp.style.display "
          + "!== \"inline\") {");
      outFile.println("      hp.style.display = \"inline\";");
      outFile.println("      arrow.src = images[\"open\"];");
      outFile.println("    } else if (hp.style.display === \"none\") {");
      outFile.println("      hp.style.display = \"inline\";");
      outFile.println("      arrow.src = images[\"open\"];");
      outFile.println("    } else {");
      outFile.println("      hp.style.display = \"none\";");
      outFile.println("      arrow.src = images[\"closed\"];");
      outFile.println("    }");
      outFile.println("  }");
      
      // function to print a single dependency in the methodDependencies report
      // see printDependency()
      outFile.println("  function b(c, deps) {");
      outFile.println("    var methodName = internedStrings[c[0]] + \".\" + internedStrings[c[1]] "
          + "+ \"::\" + internedStrings[c[2]];");
      outFile.println("    var methodSize = methodSizes[methodName];");
      outFile.println("    if (methodSize === undefined) methodSize = \"--\";");
      outFile.println("    var callstackId = \"callstack-\" + methodName;");
      outFile.println("    document.write(\"<tr>\");");
      outFile.println("    document.write(\"<td>\");");
      outFile.println("    document.write(\"<img onclick='swapShowHide(\\\"\" + "
          + "callstackId + \"\\\")'"
          + "id='dropdown-\" + callstackId + \"' "
          + "class='dropdown-img' "
          + "src=\" + images[\"closed\"] + \">\");");
      outFile.println("    document.write(\"<a class='toggle soyc-call-stack-link' "
          + "onclick='swapShowHide(\\\"\" + callstackId + \"\\\")'>\" + methodName + \"</a>\");");
      outFile.println("    document.write(\"<ul id='\" + callstackId + \"' "
          + "class='soyc-call-stack-list'>\");");
      outFile.println("    for (var i = 0; i < deps.length ; i++) {");
      outFile.println("      var s = deps[i];");
      outFile.println("      document.write(\"<li>\" + internedStrings[s[0]] + \".\" + "
          + "internedStrings[s[1]] + \"::\" + internedStrings[s[2]] + \"</li>\");");
      outFile.println("    }");
      outFile.println("    document.write(\"</ul>\");");
      outFile.println("    document.write(\"</td>\");");
      outFile.println("    document.write(\"<td class='soyc-numerical-col'>\" + "
          + "methodSize + \"</td>\");");
      outFile.println("    document.write(\"</tr>\");");
      outFile.println("  }");
      
      // follows all method dependency stacks
      outFile.println("  function j() {");
      outFile.println("    document.write(\"</table></div>\");");
      outFile.println("  }");

      // leftovers status line
      outFile.println("  function c(packageRef,classRef,packageHashRef) {");
      outFile.println("    var packageName = internedStrings[packageRef];");
      outFile.println("    var className = packageName + \".\" + internedStrings[classRef];");
      outFile.println("    var d1 = 'methodDependencies-total-" + getPermutationId() + ".html';");
      outFile.println("    document.write(\"<ul class='soyc-excl'>\");");
      outFile.println("    document.write(\"<li><a href='\" + d1 + \"#\" + className + \"'>"
          + "See why it's live</a></li>\");");
      outFile.println("    for (var sp = 1; sp <= "
          + globalInformation.getNumFragments() + "; sp++) {");
      outFile.println("      var d2 = 'methodDependencies-sp' + sp + '-" + getPermutationId() + ".html';");
      outFile.println("      document.write(\"<li><a href='\" + d2 + \"#\" + className +\"'>"
          + " See why it's not exclusive to s.p. #\" + sp + \" (\" + spl[sp - 1] + \")"
          + "</a></li>\");");
      outFile.println("    }");
      outFile.println("    document.write(\"</ul>\");");
      outFile.println("  }");

      // leftovers status package header line
      outFile.println("  function d(packageRef) {");
      outFile.println("    document.write(\"<div class='soyc-pkg-break'>Package: \" + "
          + "internedStrings[packageRef] + \"</div>\");");
      outFile.println("  }");

      // leftovers status class header line
      outFile.println("  function e(packageRef,classRef,classHashRef) {");
      outFile.println("    document.write(\"<a name='\" + classHashRef + \"'></a><h3>\" + "
          + "internedStrings[packageRef] + \".\" + internedStrings[classRef] + \"</h3>\");");
      outFile.println("  }");

      // split point has a class with code in the initial fragment - no link
      outFile.println("  function f() {");
      outFile.println("    document.write(\"<p>Some code is included in the initial fragment"
          + "</p>\");");
      outFile.println("  }");

      // split point has a class with code in the initial fragment
      outFile.println("  function g(packageRef, classRef, packageHashRef) {");
      outFile.println("    document.write(\"<p>Some code is included in the initial fragment "
          + "(<a href='methodDependencies-initial-\" + internedStrings[packageHashRef] + \"-"
          + getPermutationId()
          + ".html#\" + internedStrings[packageRef] + \".\" + "
          + "internedStrings[classRef] + \"'> See why</a>)</p>\");");
      outFile.println("  }");

      // split point has code from class
      outFile.println("  function h(packageRef, classRef, sp) {");
      outFile.println("    document.write(\"<p>Some code downloads with split point \" + sp + "
          + "\": \" + spl[sp - 1] + \"</p>\");");
      outFile.println("  }");

      // some code is left over
      outFile.println("  function i() {");
      outFile.println("    document.write(\"<p>Some code is left over:</p>\");");
      outFile.println("  }");
    }

    /**
     * Prints links to each split point showing why a leftover fragment isn't
     * exclusive.
     */
    private void printLeftoversStatus(PrintWriter outFile, String packageName,
        String className) {
      outFile.println("c(" + frozen.get(packageName) + ","
          + frozen.get(getClassSubstring(className)) + ","
          + frozen.get(hashedFilenameFragment(packageName)) + ");");
    }

    /**
     * Prints a div containing the package name in a blue block.
     */
    private void printPackageHeader(PrintWriter outFile, String packageName) {
      outFile.print("d(" + frozen.get(packageName) + ");");
    }
  }

  /**
   * By a convention shared with the compiler, the initial download is fragment
   * number 0.
   */
  private static final int FRAGMENT_NUMBER_INITIAL_DOWNLOAD = 0;

  /**
   * Just within this file, the convention is that the total program is fragment
   * number -1.
   */
  private static final int FRAGMENT_NUMBER_TOTAL_PROGRAM = -1;

  /**
   * A pattern describing the name of dependency graphs for code fragments
   * corresponding to a specific split point. These can be either exclusive
   * fragments or fragments of code for split points in the initial load
   * sequence.
   */
  private static final Pattern PATTERN_SP_INT = Pattern.compile("sp([0-9]+)");

  public static void makeTopLevelHtmlForAllPerms(
      Map<String, List<String>> allPermsInfo, OutputDirectory outDir)
      throws IOException {
    PrintWriter outFile = new PrintWriter(outDir.getOutputStream("index.html"));
    addStandardHtmlProlog(outFile, "Compile report", "Compile report",
        "Overview of permutations");
    outFile.println("<ul>");

    // in order to print these in ascending order, we have to sort by
    // integers
    SortedSet<Integer> sortedPermIds = new TreeSet<Integer>();
    for (String permutationId : allPermsInfo.keySet()) {
      sortedPermIds.add(Integer.parseInt(permutationId));
    }

    for (Integer sortedPermId : sortedPermIds) {
      String permutationId = Integer.toString(sortedPermId);
      List<String> permutationInfoList = allPermsInfo.get(permutationId);
      outFile.print("<li>Permutation " + permutationId);

      for (String desc : permutationInfoList) {
        outFile.println("  (" + desc + ")");
      }
      outFile.println("<ul>");
      outFile.println("<li>");
      outFile.println("<a href=\"SoycDashboard-" + permutationId
          + "-index.html\">Split Point Report</a>");
      outFile.println("</li>");
      outFile.println("<li>");
      outFile.println("<a href=\"CompilerMetrics-" + permutationId
          + "-index.html\">Compiler Metrics</a>");
      outFile.println("</li>");

      outFile.println("</ul>");
      outFile.println("</li>");
    }
    outFile.println("</ul>");
    addStandardHtmlEnding(outFile);
    outFile.close();
  }

  /**
   * @return given "com.foo.myClass" or "com.foo.myClass::myMethod" returns
   *         "myClass"
   */
  static String getClassSubstring(String fullMethodName) {
    if (fullMethodName.length() == 0) {
      return "";
    }
    int startIndex = getPackageSubstring(fullMethodName).length() + 1;
    int endIndex = fullMethodName.indexOf("::");
    if (endIndex == -1) {
      endIndex = fullMethodName.length();
    }
    if (startIndex > endIndex || startIndex > fullMethodName.length()) {
      return "";
    }
    return fullMethodName.substring(startIndex, endIndex);
  }

  /**
   * @return given "com.foo.myClass::myMethod" returns "myMethod"
   */
  static String getMethodSubstring(String fullMethodName) {
    int index = fullMethodName.indexOf("::");
    if (index == -1) {
      return "";
    }
    index += 2;
    if (index >= fullMethodName.length()) {
      return "";
    }
    return fullMethodName.substring(index);
  }

  /**
   * @return given "com.foo.myClass" or "com.foo.myClass::myMethod" returns
   *         "com.foo"
   */
  static String getPackageSubstring(String fullMethodName) {
    int endIndex = fullMethodName.lastIndexOf('.');
    if (endIndex == -1) {
      endIndex = fullMethodName.length();
    }
    return fullMethodName.substring(0, endIndex);
  }

  private static void addSmallHtmlProlog(final PrintWriter outFile, String title) {
    outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
    outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
    outFile.println("<html>");
    outFile.println("<head>");
    outFile.println("<title>");
    outFile.println(title);
    outFile.println("</title>");
    outFile.println("<style type=\"text/css\" media=\"screen\">");
    outFile.println("@import url('goog.css');");
    outFile.println("@import url('inlay.css');");
    outFile.println("@import url('soyc.css');");
    outFile.println("</style>");
    outFile.println("</head>");
  }

  private static void addStandardHtmlEnding(final PrintWriter out) {
    out.println("</div>");
    out.println("</body>");
    out.println("</html>");
  }

  private static void addStandardHtmlProlog(final PrintWriter outFile,
      String title, String header1, String header2) {
    outFile.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"");
    outFile.println("\"http://www.w3.org/TR/html4/strict.dtd\">");
    outFile.println("<html>");
    outFile.println("<head>");
    outFile.println("<script type=\"text/javascript\">");
    outFile.println("function show(elementName)");
    outFile.println("{");
    outFile.println("hp = document.getElementById(elementName);");
    outFile.println("hp.style.visibility = \"Visible\";");
    outFile.println("}");
    outFile.println("function hide(elementName)");
    outFile.println("{");
    outFile.println("hp = document.getElementById(elementName);");
    outFile.println("hp.style.visibility = \"Hidden\";");
    outFile.println("}");
    outFile.println("</script>");
    outFile.println("<title>");
    outFile.println(title);
    outFile.println("</title>");
    outFile.println("<style type=\"text/css\" media=\"screen\">");
    outFile.println("@import url('goog.css');");
    outFile.println("@import url('inlay.css');");
    outFile.println("@import url('soyc.css');");
    outFile.println("</style>");
    outFile.println("</head>");
    outFile.println("<body>");
    outFile.println("<div class=\"g-doc\">");
    outFile.println("<div id=\"hd\" class=\"g-section g-tpl-50-50 g-split\">");
    outFile.println("<div class=\"g-unit g-first\">");
    outFile.println("<p>");
    outFile.println("<a href=\"index.html\" id=\"gwt-logo\" class=\"soyc-ir\">");
    outFile.println("<span>Google Web Toolkit</span>");
    outFile.println("</a>");
    outFile.println("</p>");
    outFile.println("</div>");
    outFile.println("<div class=\"g-unit\">");
    outFile.println("</div>");
    outFile.println("</div>");
    outFile.println("<div id=\"soyc-appbar-lrg\">");
    outFile.println("<div class=\"g-section g-tpl-75-25 g-split\">");
    outFile.println("<div class=\"g-unit g-first\">");
    outFile.println("<h1>" + header1 + "</h1>");
    outFile.println("</div>");
    outFile.println("<div class=\"g-unit\"></div>");
    outFile.println("</div>");
    outFile.println("</div>");
    outFile.println("<div id=\"bd\">");
    if (header2 != null && header2.length() > 0) {
      outFile.println("<h2>" + header2 + "</h2>");
    }
  }

  private static String classesInPackageFileName(SizeBreakdown breakdown,
      String permutationId) {
    return breakdown.getId() + "_" + permutationId + "_Classes.html";
  }

  private String escapeJSString(String str) {
    // TODO(rluble): make into a Util routine.
    return str.replaceAll("/", "\\/");
  }

  private static String escapeXml(String unescaped) {
    // TODO(rluble): see why SizeMapRecorder.escapeXML is different from Util.escapeXML. If two
    // different versions are needed at all move SizeMapRecorder.escapeXML to Util.
    return SizeMapRecorder.escapeXml(unescaped);
  }

  /**
   * Convert a potentially long string into a short file name. The current
   * implementation simply hashes the long name.
   */
  private static String hashedFilenameFragment(String longFileName) {
    try {
      return Util.computeStrongName(longFileName.getBytes(Util.DEFAULT_ENCODING));
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException(e);
    }
  }

  private static String headerLineForBreakdown(SizeBreakdown breakdown) {
    return "(Analyzing code subset: " + breakdown.getDescription() + ")";
  }

  private static String shellFileName(SizeBreakdown breakdown,
      String permutationId) {
    return breakdown.getId() + "-" + permutationId + "-overallBreakdown.html";
  }

  /**
   * Global information for this permutation.
   */
  private final GlobalInformation globalInformation;

  private final OutputDirectory outDir;

  MakeTopLevelHtmlForPerm(GlobalInformation globalInformation,
      OutputDirectory outDir) {
    this.globalInformation = globalInformation;
    this.outDir = outDir;
  }

  public void makeBreakdownShell(SizeBreakdown breakdown) throws IOException {
    Map<String, CodeCollection> nameToCodeColl = breakdown.nameToCodeColl;
    Map<String, LiteralsCollection> nameToLitColl = breakdown.nameToLitColl;
    String packageBreakdownFileName = makePackageHtml(breakdown);
    String codeTypeBreakdownFileName = makeCodeTypeHtml(breakdown,
        nameToCodeColl, nameToLitColl);

    PrintWriter outFile = new PrintWriter(getOutFile(shellFileName(breakdown,
        getPermutationId())));

    addStandardHtmlProlog(outFile, "Application breakdown analysis",
        "Application breakdown analysis", "");

    String popupName = "packageBreakdownPopup";
    String popupTitle = "Package breakdown";
    String popupBody = "The package breakdown blames pieces of JavaScript "
        + "code on Java packages wherever possible.  Note that this is not possible for all "
        + "code, so the sizes of the packages here will not normally add up to the full code "
        + "size.  More specifically, the sum will exclude strings, whitespace, and a few pieces "
        + "of JavaScript code that are produced during compilation but cannot be attributed to "
        + "any Java package.";

    outFile.println("<h2>");
    addPopupLink(outFile, popupName, popupTitle, null);
    outFile.println("</h2></div>");
    addPopup(outFile, popupName, popupTitle, popupBody);
    outFile.println("<iframe class='soyc-iframe-package' src=\""
        + packageBreakdownFileName + "\" scrolling=auto></iframe>");

    popupName = "codeTypeBreakdownPopup";
    popupTitle = "Code Type Breakdown";
    popupBody = "The code type breakdown breaks down the JavaScript code according to its "
        + "type or function.  For example, it tells you how much of your code can be attributed to "
        + "JRE, GWT-RPC, etc.  As above, strings and some other JavaScript snippets are not "
        + "included in the breakdown.";
    outFile.println("<h2>");
    addPopupLink(outFile, popupName, popupTitle, null);
    outFile.println("</h2>");
    addPopup(outFile, popupName, popupTitle, popupBody);

    outFile.println("<iframe class='soyc-iframe-code' src=\""
        + codeTypeBreakdownFileName + "\" scrolling=auto></iframe>");
    outFile.println("</div>");

    addStandardHtmlEnding(outFile);
    outFile.close();
  }

  public void makeCodeTypeClassesHtmls(SizeBreakdown breakdown)
      throws IOException {
    HashMap<String, CodeCollection> nameToCodeColl = breakdown.nameToCodeColl;

    for (String codeType : nameToCodeColl.keySet()) {

      // construct file name
      String outFileName = breakdown.getId() + "_" + codeType + "-"
          + getPermutationId() + "Classes.html";

      float sumSize = 0f;
      TreeMap<Integer, Set<String>> sortedClasses = new TreeMap<Integer, Set<String>>(
          Collections.reverseOrder());

      for (String className : nameToCodeColl.get(codeType).classes) {
        if (breakdown.classToSize.containsKey(className)) {
          int curSize = 0;
          if (breakdown.classToSize.containsKey(className)) {
            curSize = breakdown.classToSize.get(className);
          }
          if (curSize != 0) {
            if (sortedClasses.containsKey(curSize)) {
              Set<String> existingSet = sortedClasses.get(curSize);
              existingSet.add(className);
              sortedClasses.put(curSize, existingSet);
            } else {
              Set<String> newSet = new TreeSet<String>();
              newSet.add(className);
              sortedClasses.put(curSize, newSet);
            }
            sumSize += curSize;
          }
        }
      }

      final PrintWriter outFile = new PrintWriter(getOutFile(outFileName));
      addStandardHtmlProlog(outFile, "Classes in package " + codeType,
          "Classes in package " + codeType, headerLineForBreakdown(breakdown));
      outFile.println("<table class=\"soyc-table\">");
      outFile.println("<colgroup>");
      outFile.println("<col id=\"soyc-splitpoint-type-col\">");
      outFile.println("<col id=\"soyc-splitpoint-size-col\">");
      outFile.println("</colgroup>");
      outFile.println("<thead>");
      outFile.println("<th>Code type</th>");
      outFile.println("<th>");
      outFile.println("<th class=\"soyc-numerical-col-header\">");
      outFile.println("Size <span class=\"soyc-th-units\">(Bytes)</span>");
      outFile.println("</th>");
      outFile.println("<th class=\"soyc-numerical-col-header\">% of total</th>");
      outFile.println("</thead>");
      
      NumberFormat bytesFormatter = NumberFormat.getInstance();
      bytesFormatter.setGroupingUsed(true);
      
      NumberFormat percentFormatter = NumberFormat.getPercentInstance();
      percentFormatter.setMinimumFractionDigits(1);
      percentFormatter.setMaximumFractionDigits(1);

      for (Integer size : sortedClasses.keySet()) {
        Set<String> classNames = sortedClasses.get(size);
        for (String className : classNames) {
          float perc = (float) size / sumSize;
          outFile.println("<tr>");
          outFile.println("<td>" + className + "</a></td>");
          outFile.println("<td class=\"soyc-bargraph-col\">");
          outFile.println("<div class=\"soyc-bar-graph goog-inline-block\">");
          // CHECKSTYLE_OFF
          outFile.println("<div style=\"width:" + (perc * 100.0)
              + "%;\" class=\"soyc-bar-graph-fill goog-inline-block\"></div>");
          // CHECKSTYLE_ON
          outFile.println("</div>");
          outFile.println("</td>");
          outFile.println("<td class=\"soyc-numerical-col\">");
          outFile.println(bytesFormatter.format(size));
          outFile.println("</td>");
          outFile.println("<td class=\"soyc-percent-col\">" + 
              percentFormatter.format(perc) + "</td>");
          outFile.println("</tr>");
        }
      }
      addStandardHtmlEnding(outFile);
      outFile.close();
    }
  }

  public void makeCompilerMetricsPermFiles(ModuleMetricsArtifact moduleMetrics,
      PrecompilationMetricsArtifact precompilationMetrics,
      CompilationMetricsArtifact compilationMetrics) throws IOException {
    String outFileName = "CompilerMetrics-"
        + precompilationMetrics.getPermutationBase() + "-index.html";
    PrintWriter outFile = new PrintWriter(getOutFile(outFileName));
    String title = "Compiler Metrics for Permutation "
        + compilationMetrics.getPermutationId();
    addStandardHtmlProlog(outFile, title, title, "Build Time Metrics");
    
    NumberFormat elapsedFormatter = NumberFormat.getInstance();
    elapsedFormatter.setGroupingUsed(true);
    elapsedFormatter.setMinimumFractionDigits(3);
    elapsedFormatter.setMaximumFractionDigits(3);
    
    outFile.println("<div id=\"bd\">");
    int permutationId = compilationMetrics.getPermutationId();

    // Build Time Metrics
    outFile.println("<table class=\"soyc-table\">");
    outFile.println("<colgroup>");
    outFile.println("<col id=\"soyc-buildTimePhase-col\">");
    outFile.println("<col id=\"soyc-buildTimeElapsed-col\">");
    outFile.println("</colgroup>");
    outFile.println("<thead>");
    outFile.println("<th>Phase</th>");
    outFile.println("<th class=\"soyc-numerical-col-header\">Elapsed Time</th>");
    outFile.println("</thead>");

    outFile.println("<tr>");
    outFile.println("<td>");
    outFile.println("Module Analysis");
    outFile.println("</td>");
    outFile.println("<td class=\"soyc-numerical-col\">"  
        + elapsedFormatter.format(moduleMetrics.getElapsedMilliseconds() / 1000.0) + " s");
    outFile.println("</td>");
    outFile.println("</tr>");

    outFile.println("<tr>");
    outFile.println("<td>");
    outFile.println("Precompile (may include Module Analysis)");
    outFile.println("</td>");
    outFile.println("<td class=\"soyc-numerical-col\">" 
        + elapsedFormatter.format(precompilationMetrics.getElapsedMilliseconds() / 1000.0)
        + " s");
    outFile.println("</td>");
    outFile.println("</tr>");

    outFile.println("<tr>");
    outFile.println("<td>");
    outFile.println("Compile");
    outFile.println("</td>");
    outFile.println("<td class=\"soyc-numerical-col\">" 
        + elapsedFormatter.format(compilationMetrics.getElapsedMilliseconds() / 1000.0)
        + " s");
    outFile.println("</td>");
    outFile.println("</tr>");
    outFile.println("</table>");
    
    NumberFormat referencesFormatter = NumberFormat.getInstance();
    referencesFormatter.setGroupingUsed(true);

    outFile.println("<p></p>");
    outFile.println("<h2>Source/Type Metrics</h2>");

    outFile.println("<table class=\"soyc-table\">");
    outFile.println("<colgroup>");
    outFile.println("<col id=\"soyc-typeList-col\">");
    outFile.println("<col id=\"soyc-typeReferences-col\">");
    outFile.println("</colgroup>");
    outFile.println("<thead>");
    outFile.println("<th>Description</th>");
    outFile.println("<th class=\"soyc-numerical-col-header\">References</th>");
    outFile.println("</thead>");

    String sourcesFileName = "CompilerMetrics-sources.html";
    outFile.println("<tr>");
    outFile.println("<td>");
    String popupName = "compilerMetricsSourceFiles";
    String popupTitle = "Source files";
    String popupBody = "All source files on the module source path.";
    addPopupLink(outFile, popupName, popupTitle, sourcesFileName);
    addPopup(outFile, popupName, popupTitle, popupBody);
    outFile.println("</td>");
    outFile.println("<td class=\"soyc-numerical-col\">");
    outFile.println(referencesFormatter.format(moduleMetrics.getSourceFiles().length));
    outFile.println("</td>");
    outFile.println("</tr>");
    makeCompilerMetricsSources(sourcesFileName, moduleMetrics, popupBody);

    String initialTypesFileName = "CompilerMetrics-initialTypes-"
        + permutationId + ".html";
    outFile.println("<tr>");
    outFile.println("<td>");
    popupName = "compilerMetricsInitialTypes";
    popupTitle = "Initial Type Oracle Types";
    popupBody = "All types in the type oracle after compiling sources on the source path.";
    addPopupLink(outFile, popupName, popupTitle, initialTypesFileName);
    addPopup(outFile, popupName, popupTitle, popupBody);
    outFile.println("</td>");
    outFile.println("<td class=\"soyc-numerical-col\">");
    outFile.println(referencesFormatter.format(moduleMetrics.getInitialTypes().length));
    outFile.println("</td>");
    outFile.println("</tr>");
    makeCompilerMetricsInitialTypeOracleTypes(initialTypesFileName,
        moduleMetrics, popupBody);

    String finalTypesFileName = "CompilerMetrics-finalTypes-" + permutationId
        + ".html";
    outFile.println("<tr>");
    outFile.println("<td>");
    popupName = "compilerMetricsFinalTypes";
    popupTitle = "Final Type Oracle Types";
    popupBody = "All types in the type oracle after constructing the Java AST.";
    addPopupLink(outFile, popupName, popupTitle, finalTypesFileName);
    addPopup(outFile, popupName, popupTitle, popupBody);
    outFile.println("</td>");
    outFile.println("<td class=\"soyc-numerical-col\">");
    outFile.println(referencesFormatter.format(
        precompilationMetrics.getFinalTypeOracleTypes().length));
    outFile.println("</td>");
    outFile.println("</tr>");
    makeCompilerMetricsFinalTypeOracleTypes(finalTypesFileName,
        precompilationMetrics, popupBody);

    String[] generatedTypes = getGeneratedTypes(moduleMetrics,
        precompilationMetrics);
    String generatedTypesFileName = "CompilerMetrics-generatedTypes-"
        + permutationId + ".html";
    outFile.println("<tr>");
    outFile.println("<td>");
    popupName = "compilerMetricsGeneratedTypes";
    popupTitle = "GeneratedTypes";
    popupBody = "Types that were added to the type oracle while running generators.";
    addPopupLink(outFile, popupName, popupTitle, generatedTypesFileName);
    addPopup(outFile, popupName, popupTitle, popupBody);
    outFile.println("</td>");
    outFile.println("<td class=\"soyc-numerical-col\">");
    outFile.println(referencesFormatter.format(generatedTypes.length));
    outFile.println("</td>");
    outFile.println("</tr>");
    makeCompilerMetricsGeneratedTypes(generatedTypesFileName, generatedTypes,
        popupBody);

    String astFileName = "CompilerMetrics-ast-" + permutationId + ".html";
    outFile.println("<tr>");
    outFile.println("<td>");
    popupName = "compilerMetricsAstTypes";
    popupTitle = "AST Referenced Types";
    popupBody = "All types referenced by the Java AST after performing "
        + "reachability analysis from the module EntryPoint.";
    addPopupLink(outFile, popupName, popupTitle, astFileName);
    addPopup(outFile, popupName, popupTitle, popupBody);
    outFile.println("</td>");
    outFile.println("<td class=\"soyc-numerical-col\">");
    outFile.println(referencesFormatter.format(precompilationMetrics.getAstTypes().length));
    outFile.println("</td>");
    outFile.println("</tr>");
    makeCompilerMetricsAstTypes(astFileName, precompilationMetrics, popupBody);

    String[] unreferencedTypes = getUnreferencedTypes(precompilationMetrics);
    String unreferencedFileName = "CompilerMetrics-unreferencedTypes-"
        + permutationId + ".html";
    outFile.println("<tr>");
    outFile.println("<td>");
    popupName = "compilerMetricsUnreferenceTypes";
    popupTitle = "Unreferenced Types";
    popupBody = "Types that were on the initial source path but never referenced in "
        + "the Java AST.";
    addPopupLink(outFile, popupName, popupTitle, unreferencedFileName);
    addPopup(outFile, popupName, popupTitle, popupBody);
    outFile.println("</td>");
    outFile.println("<td class=\"soyc-numerical-col\">");
    outFile.println(referencesFormatter.format(unreferencedTypes.length));
    outFile.println("</td>");
    outFile.println("</tr>");
    makeCompilerMetricsUnreferencedTypes(unreferencedFileName,
        unreferencedTypes, popupBody);
    outFile.println("</table>");

    addStandardHtmlEnding(outFile);
    outFile.close();
  }

  public void makeDependenciesHtml() throws IOException {
    for (String depGraphName : globalInformation.dependencies.keySet()) {
      makeDependenciesHtml(depGraphName,
          globalInformation.dependencies.get(depGraphName));
    }
  }

  public void makeLeftoverStatusPages() throws IOException {
    PrintWriter outFile = new PrintWriter(getOutFile(leftoversStatusFileName()));
    addStandardHtmlProlog(outFile, "Leftovers page", "Leftovers page", "");
    outFile.println("<div id=\"bd\">");
    outFile.println("<p>These classes have some leftover code, neither initial nor "
        + "exclusive to any split point:</p>");
    String curPackageName = "";
    HtmlInterner interner = new HtmlInterner();

    for (String className : globalInformation.getClassToPackage().keySet()) {
      String packageName = globalInformation.getClassToPackage().get(className);
      interner.intern(packageName);
      interner.intern(getClassSubstring(className));
      interner.intern(hashedFilenameFragment(packageName));
    }
    interner.freeze();

    outFile.println("<script language=\"javascript\">");
    interner.printInternedDataAsJs(outFile);

    for (String className : globalInformation.getClassToPackage().keySet()) {
      String packageName = globalInformation.getClassToPackage().get(className);
      if (packageName.compareTo("") == 0
          || packageName.compareTo(curPackageName) != 0) {
        curPackageName = packageName;
        interner.printPackageHeader(outFile, packageName);
      }
      interner.printClassHeader(outFile, className);
      if (globalInformation.dependencies != null) {
        interner.printLeftoversStatus(outFile, packageName, className);
      }
    }
    outFile.println("</script>");
    addStandardHtmlEnding(outFile);
    outFile.close();
  }

  public void makeLiteralsClassesTableHtmls(SizeBreakdown breakdown)
      throws IOException {
    Map<String, LiteralsCollection> nameToLitColl = breakdown.nameToLitColl;
    for (String literalType : nameToLitColl.keySet()) {
      String outFileName = literalType + "-" + getPermutationId() + "Lits.html";
      final PrintWriter outFile = new PrintWriter(getOutFile(breakdown.getId()
          + "_" + outFileName));
      addStandardHtmlProlog(outFile, "Literals of type " + literalType,
          "Literals of type " + literalType, headerLineForBreakdown(breakdown));
      outFile.println("<table width=\"80%\" style=\"font-size: 11pt;\" bgcolor=\"white\">");
      for (String literal : nameToLitColl.get(literalType).literals) {
        if (literal.trim().length() == 0) {
          literal = "[whitespace only string]";
        }
        String escliteral = escapeXml(literal);
        outFile.println("<tr>");
        outFile.println("<td>" + escliteral + "</td>");
        outFile.println("</tr>");
      }
      outFile.println("</table>");
      outFile.println("<center>");
      addStandardHtmlEnding(outFile);
      outFile.close();
    }
  }

  /**
   * Make size breakdowns for each package for one code collection.
   */
  public void makePackageClassesHtmls(SizeBreakdown breakdown,
      DependencyLinker depLinker) throws IOException {
    PrintWriter outFile = new PrintWriter(getOutFile(classesInPackageFileName(
        breakdown, getPermutationId())));
    addStandardHtmlProlog(outFile, "Classes in  " + breakdown.getDescription(),
        "Classes in " + breakdown.getDescription(),
        headerLineForBreakdown(breakdown));

    String[] packageNames = globalInformation.getPackageToClasses().keySet().toArray(
        new String[0]);
    Arrays.sort(packageNames);
    for (String packageName : packageNames) {
      TreeMap<Integer, Set<String>> sortedClasses = new TreeMap<Integer, Set<String>>(
          Collections.reverseOrder());
      int sumSize = 0;
      for (String className : globalInformation.getPackageToClasses().get(
          packageName)) {
        int curSize = 0;
        if (!breakdown.classToSize.containsKey(className)) {
          // This class not present in this code collection
        } else {
          curSize = breakdown.classToSize.get(className);
        }
        if (curSize != 0f) {
          if (sortedClasses.containsKey(curSize)) {
            Set<String> existingSet = sortedClasses.get(curSize);
            existingSet.add(className);
            sortedClasses.put(curSize, existingSet);
          } else {
            Set<String> newSet = new TreeSet<String>();
            newSet.add(className);
            sortedClasses.put(curSize, newSet);
          }
          sumSize += curSize;
        }
      }

      if (sortedClasses.size() > 0) {
        outFile.println("<p>");
        outFile.println("<table class=\"soyc-table\">");
        outFile.print("<colgroup>");
        outFile.print("<col id=\"soyc-splitpoint-type-col\">");
        outFile.print("<col id=\"soyc-splitpoint-size-col\">");
        outFile.println("</colgroup>");
        outFile.print("<thead>");
        outFile.print("<a name=\"" + hashedFilenameFragment(packageName)
            + "\"></a><th>Package: " + packageName + "</th>");
        outFile.println("<th></th>");
        outFile.println("<th class=\"soyc-numerical-col-header\">");
        outFile.println("Size <span class=\"soyc-th-units\">(Bytes)</span>");
        outFile.println("</th>");
        outFile.println("<th class=\"soyc-numerical-col-header\">% of total</th>");
        outFile.print("</thead>");
        
        NumberFormat bytesFormatter = NumberFormat.getInstance();
        bytesFormatter.setGroupingUsed(true);
        
        NumberFormat percentFormatter = NumberFormat.getPercentInstance();
        percentFormatter.setMinimumFractionDigits(1);
        percentFormatter.setMaximumFractionDigits(1);

        for (Integer size : sortedClasses.keySet()) {
          Set<String> classNames = sortedClasses.get(size);
          for (String className : classNames) {
            String drillDownFileName = depLinker.dependencyLinkForClass(className);
            float perc = (float) size / (float) sumSize;
            outFile.println("<tr>");
            if (drillDownFileName == null) {
              outFile.println("<td>" + className + "</td>");
            } else {
              outFile.println("<td><a href=\"" + drillDownFileName
                  + "\" target=\"_top\">" + className + "</a></td>");
            }
            outFile.println("<td class=\"soyc-bargraph-col\">");
            outFile.println("<div class=\"soyc-bar-graph goog-inline-block\">");
            // CHECKSTYLE_OFF
            outFile.println("<div style=\"width:" + (perc * 100.0)
                + "%;\" class=\"soyc-bar-graph-fill goog-inline-block\"></div>");
            // CHECKSTYLE_ON
            outFile.println("</div>");
            outFile.println("</td>");
            outFile.println("<td class=\"soyc-numerical-col\">");
            outFile.println(bytesFormatter.format(size));
            outFile.println("</td>");
            outFile.println("<td class=\"soyc-percent-col\">" + 
                percentFormatter.format(perc) + "</td>");
            outFile.println("</tr>");
          }
        }
        outFile.println("</table>");
        outFile.println("</p>");
      }
    }
    addStandardHtmlEnding(outFile);
    outFile.close();
  }

  public void makeSplitStatusPages() throws IOException {
    PrintWriter outFile = new PrintWriter(getOutFile(splitStatusFileName()));

    addStandardHtmlProlog(outFile, "Split point status", "Split point status",
        "");
    outFile.println("<div id=\"bd\">");

    HtmlInterner interner = new HtmlInterner();
    for (String className : globalInformation.getClassToPackage().keySet()) {
      String packageName = globalInformation.getClassToPackage().get(className);
      interner.intern(packageName);
      interner.intern(getClassSubstring(className));
      interner.intern(hashedFilenameFragment(packageName));
    }
    interner.freeze();

    outFile.println("<script language=\"javascript\">");
    interner.printInternedDataAsJs(outFile);

    String curPackageName = "";
    for (String className : globalInformation.getClassToPackage().keySet()) {

      String packageName = globalInformation.getClassToPackage().get(className);
      if (packageName.compareTo("") == 0
          || packageName.compareTo(curPackageName) != 0) {
        curPackageName = packageName;
        interner.printPackageHeader(outFile, packageName);
      }

      interner.printClassHeader(outFile, className);

      if (globalInformation.getInitialCodeBreakdown().classToSize.containsKey(className)) {
        if (globalInformation.dependencies != null) {
          interner.printHasInitialFragment(outFile, className);
        } else {
          interner.printHasInitialFragment(outFile);
        }
      }
      for (int sp : splitPointsWithClass(className)) {
        interner.printHasCodeInSplitPoint(outFile, className, sp);
      }
      if (globalInformation.getLeftoversBreakdown().classToSize.containsKey(className)) {
        interner.printSomeCodeLeftover(outFile);
        interner.printLeftoversStatus(outFile, packageName, className);
      }
    }
    outFile.println("</script>");

    addStandardHtmlEnding(outFile);
    outFile.close();
  }

  public void makeTopLevelShell() throws IOException {

    String permutationId = getPermutationId();
    PrintWriter outFile = new PrintWriter(getOutFile("SoycDashboard" + "-"
        + getPermutationId() + "-index.html"));

    addStandardHtmlProlog(outFile, "Compile report: Permutation "
        + permutationId, "Compile report: Permutation " + permutationId, "");
    
    NumberFormat bytesFormatter = NumberFormat.getInstance();
    bytesFormatter.setGroupingUsed(true);

    outFile.println("<div id=\"bd\">");
    outFile.println("<div id=\"soyc-summary\" class=\"g-section\">");
    outFile.println("<dl>");
    outFile.println("<dt>Full code size</dt>");
    outFile.println("<dd class=\"value\">"
        + bytesFormatter.format(globalInformation.getTotalCodeBreakdown().sizeAllCode) 
        + " Bytes</dd>");
    outFile.println("<dd class=\"report\"><a href=\"total-" + permutationId
        + "-overallBreakdown.html\">Report</a></dd>");

    outFile.println("</dl>");
    outFile.println("<dl>");
    outFile.println("<dt>Initial download size</dt>");
    // TODO(kprobst) -- add percentage here: (48%)</dd>");
    outFile.println("<dd class=\"value\">"
        + bytesFormatter.format(globalInformation.getInitialCodeBreakdown().sizeAllCode)
        + " Bytes</dd>");
    outFile.println("<dd class=\"report\"><a href=\"initial-" + permutationId
        + "-overallBreakdown.html\">Report</a></dd>");
    outFile.println("</dl>");
    outFile.println("<dl>");

    outFile.println("<dt>Left over code</dt>");
    outFile.println("<dd class=\"value\">"
        + bytesFormatter.format(globalInformation.getLeftoversBreakdown().sizeAllCode) 
        + " Bytes</dd>");
    outFile.println("<dd class=\"report\"><a href=\"leftovers-" + permutationId
        + "-overallBreakdown.html\">Report</a></dd>");
    outFile.println("</dl>");
    outFile.println("</div>");
    outFile.println("<table id=\"soyc-table-splitpoints\" class=\"soyc-table\">");
    outFile.println("<caption>");

    outFile.println("<strong>Split Points</strong>");
    outFile.println("</caption>");
    outFile.println("<colgroup>");
    outFile.println("<col id=\"soyc-splitpoint-number-col\">");
    outFile.println("<col id=\"soyc-splitpoint-location-col\">");
    outFile.println("<col id=\"soyc-splitpoint-size-col\">");
    outFile.println("</colgroup>");
    outFile.println("<thead>");

    outFile.println("<th>#</th>");
    outFile.println("<th>Location</th>");
    outFile.println("<th></th>");
    outFile.println("<th class=\"soyc-numerical-col-header\">");
    outFile.println("Size <span class=\"soyc-th-units\">(Bytes)</span>");
    outFile.println("</th>");
    outFile.println("<th class=\"soyc-numerical-col-header\">% of total</th>");
    outFile.println("</thead>");
    outFile.println("<tbody>");
    
    NumberFormat percentFormatter = NumberFormat.getPercentInstance();
    percentFormatter.setMinimumFractionDigits(1);
    percentFormatter.setMaximumFractionDigits(1);

    if (globalInformation.getNumFragments() >= 1) {

      int numFragments = globalInformation.getNumFragments();
      int maxSize = globalInformation.getTotalCodeBreakdown().sizeAllCode;

      for (int fragment = FRAGMENT_NUMBER_TOTAL_PROGRAM; fragment <= numFragments + 1; fragment++) {
        SizeBreakdown breakdown;
        if (fragment == FRAGMENT_NUMBER_TOTAL_PROGRAM
            || fragment == numFragments + 1 // leftovers
            || fragment == FRAGMENT_NUMBER_INITIAL_DOWNLOAD) {
          continue;
        }

        breakdown = globalInformation.fragmentCodeBreakdown(fragment);

        String drillDownFileName = shellFileName(breakdown, getPermutationId());
        final List<String> fragmentDescriptors = globalInformation.getFragmentDescriptors(fragment);
        String[] escapedFragmentDescriptors =
            new String[fragmentDescriptors.size()];
        for (int i = 0; i < fragmentDescriptors.size(); i++) {
          escapedFragmentDescriptors[i] =
              escapeXml(fragmentDescriptors.get(i));
        }

        String fragmentDescription = Joiner.on("<BR>").join(escapedFragmentDescriptors);

        int size = breakdown.sizeAllCode;
        float perc = (float) size / (float) maxSize;

        outFile.println("<tr>");
        outFile.println("<td>" + fragment + "</td>");
        outFile.print("<td><a href=\"" + drillDownFileName + "\">" + fragmentDescription
            + "</a></td>");
        outFile.println("<td class=\"soyc-bargraph-col\">");
        outFile.println("<div class=\"soyc-bar-graph goog-inline-block\">");
        // CHECKSTYLE_OFF
        outFile.println("<div style=\"width:" + (perc * 100.0)
            + "%;\" class=\"soyc-bar-graph-fill goog-inline-block\"></div>");
        // CHECKSTYLE_ON
        outFile.println("</div>");
        outFile.println("</td>");
        outFile.println("<td class=\"soyc-numerical-col\">");
        outFile.println(bytesFormatter.format(size));
        outFile.println("</td>");
        outFile.println("<td class=\"soyc-percent-col\">" + 
            percentFormatter.format(perc) + "</td>");
        outFile.println("</tr>");
      }
    }
    outFile.println("</tbody>");
    outFile.println("</table>");
    outFile.println("</div>");
    addStandardHtmlEnding(outFile);
    outFile.close();
  }

  private void addPopup(PrintWriter outFile, String popupName,
      String popupTitle, String popupBody) {
    outFile.println("<div class=\"soyc-popup\" id=\"" + popupName + "\">");
    outFile.println("<table>");
    outFile.println("<tr><th><b>" + popupTitle + "</b></th></tr>");
    outFile.println("<tr><td>" + popupBody + "</td></tr>");
    outFile.println("</table>");
    outFile.println("</div>");
  }

  private void addPopupLink(PrintWriter outFile, String popupName,
      String popupTitle, String href) {
    outFile.println("<a ");
    if (href != null) {
      outFile.println("href=\"" + href + "\"");
    }
    outFile.println("style=\"cursor:default;\" onMouseOver=\"show('"
        + popupName + "');\" " + "onMouseOut=\"hide('" + popupName + "');\">"
        + popupTitle + "</a>");
  }

  /**
   * Returns a file name for the dependencies list.
   */
  private String dependenciesFileName(String depGraphName) {
    return "methodDependencies-" + depGraphName + "-" + getPermutationId() + ".html";
  }

  private String[] getGeneratedTypes(ModuleMetricsArtifact moduleMetrics,
      PrecompilationMetricsArtifact precompilationMetrics) {
    List<String> initialTypes = Lists.create(moduleMetrics.getInitialTypes());
    Set<String> generatedTypes = Sets.create(precompilationMetrics.getFinalTypeOracleTypes());
    generatedTypes.removeAll(initialTypes);
    String[] results = generatedTypes.toArray(new String[generatedTypes.size()]);
    Arrays.sort(results);
    return results;
  }

  /**
   * Return a {@link java.io.File} object for a file to be emitted into the
   * output directory.
   */
  private OutputStream getOutFile(String localFileName) throws IOException {
    return outDir.getOutputStream(localFileName);
  }

  /**
   * @return the ID for the current permutation
   */
  private String getPermutationId() {
    return globalInformation.getPermutationId();
  }

  private String[] getUnreferencedTypes(
      PrecompilationMetricsArtifact precompilationMetrics) {
    List<String> astTypes = Lists.create(precompilationMetrics.getAstTypes());
    Set<String> unreferencedTypes = Sets.create(precompilationMetrics.getFinalTypeOracleTypes());
    unreferencedTypes.removeAll(astTypes);
    String[] results = unreferencedTypes.toArray(new String[unreferencedTypes.size()]);
    Arrays.sort(results);
    return results;
  }

  /**
   * Describe the code covered by the dependency graph with the supplied name.
   */
  private String inferDepGraphDescription(String depGraphName) {
    if (depGraphName.equals("initial")) {
      return "Initially Live Code";
    }

    if (depGraphName.equals("total")) {
      return "All Code";
    }

    Matcher matcher = PATTERN_SP_INT.matcher(depGraphName);
    if (matcher.matches()) {
      int splitPoint = Integer.valueOf(matcher.group(1));
      if (isInitialSplitPoint(splitPoint)) {
        return "Code Becoming Live at Split Point " + splitPoint;
      } else {
        return "Code not Exclusive to Split Point " + splitPoint;
      }
    }

    throw new RuntimeException("Unexpected dependency graph name: "
        + depGraphName);
  }

  /**
   * Returns whether a split point is initial or not.
   *
   * @param splitPoint
   * @returns true of the split point is initial, false otherwise
   */
  private boolean isInitialSplitPoint(int splitPoint) {
    return globalInformation.getInitialFragmentLoadSequence().contains(
        splitPoint);
  }

  /**
   * Makes a file name for a leftovers status file.
   *
   * @return the file name of the leftovers status file
   */
  private String leftoversStatusFileName() {
    return "leftoverStatus-" + getPermutationId() + ".html";
  }

  /**
   * Produces an HTML file that breaks down by code type.
   *
   * @param breakdown
   * @param nameToCodeColl
   * @param nameToLitColl
   * @return the name of the produced file
   * @throws IOException
   */
  private String makeCodeTypeHtml(SizeBreakdown breakdown,
      Map<String, CodeCollection> nameToCodeColl,
      Map<String, LiteralsCollection> nameToLitColl) throws IOException {
    String outFileName = breakdown.getId() + "-" + getPermutationId()
        + "-codeTypeBreakdown.html";
    int sumSize = 0;
    TreeMap<Integer, Set<String>> sortedCodeTypes = new TreeMap<Integer, Set<String>>(
        Collections.reverseOrder());

    for (String codeType : nameToCodeColl.keySet()) {
      int curSize = nameToCodeColl.get(codeType).getCumSize(breakdown);
      sumSize += curSize;
      if (curSize != 0) {
        if (sortedCodeTypes.containsKey(curSize)) {
          Set<String> existingSet = sortedCodeTypes.get(curSize);
          existingSet.add(codeType);
          sortedCodeTypes.put(curSize, existingSet);
        } else {
          Set<String> newSet = new TreeSet<String>();
          newSet.add(codeType);
          sortedCodeTypes.put(curSize, newSet);
        }
      }
    }

    final PrintWriter outFile = new PrintWriter(getOutFile(outFileName));
    addSmallHtmlProlog(outFile, "Code breakdown");
    outFile.println("<body class=\"soyc-breakdown\">");
    outFile.println("<div class=\"g-doc\">");

    outFile.println("<table class=\"soyc-table\">");
    outFile.println("<colgroup>");
    outFile.println("<col id=\"soyc-splitpoint-type-col\">");
    outFile.println("<col id=\"soyc-splitpoint-size-col\">");
    outFile.println("</colgroup>");
    outFile.println("<thead>");
    outFile.println("<th>Type</th>");
    outFile.println("<th></th>");
    outFile.println("<th class=\"soyc-numerical-col-header\">");
    outFile.println("Size <span class=\"soyc-th-units\">(Bytes)</span>");
    outFile.println("</th>");
    outFile.println("<th class=\"soyc-numerical-col-header\">% of total</th>");
    outFile.println("</thead>");
    
    NumberFormat bytesFormatter = NumberFormat.getInstance();
    bytesFormatter.setGroupingUsed(true);
    
    NumberFormat percentFormatter = NumberFormat.getPercentInstance();
    percentFormatter.setMinimumFractionDigits(1);
    percentFormatter.setMaximumFractionDigits(1);

    for (Integer size : sortedCodeTypes.keySet()) {
      Set<String> codeTypes = sortedCodeTypes.get(size);
      for (String codeType : codeTypes) {
        String drillDownFileName = breakdown.getId() + "_" + codeType + "-"
            + getPermutationId() + "Classes.html";
        float perc = (float) size / (float) sumSize;
        outFile.println("<tr>");
        outFile.println("<td><a href=\"" + drillDownFileName
            + "\" target=\"_top\">" + codeType + "</a></td>");
        outFile.println("<td class=\"soyc-bargraph-col\">");
        outFile.println("<div class=\"soyc-bar-graph goog-inline-block\">");
        // CHECKSTYLE_OFF
        outFile.println("<div style=\"width:" + (perc * 100.0)
            + "%;\" class=\"soyc-bar-graph-fill goog-inline-block\"></div>");
        // CHECKSTYLE_ON
        outFile.println("</div>");
        outFile.println("</td>");
        outFile.println("<td class=\"soyc-numerical-col\">");
        outFile.println(bytesFormatter.format(size));
        outFile.println("</td>");
        outFile.println("<td class=\"soyc-percent-col\">" + 
            percentFormatter.format(perc) + "</td>");
        outFile.println("</tr>");
      }
    }
    outFile.println("</table>");

    int stringSize = nameToLitColl.get("string").size;
    String drillDownFileName = breakdown.getId() + "_string-"
        + getPermutationId() + "Lits.html";
    outFile.println("<p class=\"soyc-breakdown-strings\">" + stringSize
        + " bytes occupied by <a href=\"" + drillDownFileName
        + "\" target=\"_top\">Strings</a></p>");
    int unaccountedForSize = breakdown.sizeAllCode - sumSize - stringSize;
    outFile.println("<p class=\"soyc-breakdown-strings\">"
        + unaccountedForSize
        + " bytes of the JavaScript output cannot be attributed to any package or code type.</p>");
    addStandardHtmlEnding(outFile);
    outFile.close();
    return outFileName;
  }

  private void makeCompilerMetricsAstTypes(String outFileName,
      PrecompilationMetricsArtifact precompilationMetrics, String helpText)
      throws IOException {
    PrintWriter outFile = new PrintWriter(getOutFile(outFileName));
    String title = "AST Types";
    addStandardHtmlProlog(outFile, title, title, "");
    outFile.println("<p>");
    outFile.println(helpText);
    outFile.println("</p>");
    outFile.println("<pre>");
    String[] types = precompilationMetrics.getAstTypes();
    Arrays.sort(types);
    for (String type : types) {
      outFile.println(type);
    }
    outFile.println("</pre>");
    addStandardHtmlEnding(outFile);
    outFile.close();
  }

  private void makeCompilerMetricsFinalTypeOracleTypes(String outFileName,
      PrecompilationMetricsArtifact precompilationMetrics, String helpText)
      throws IOException {
    PrintWriter outFile = new PrintWriter(getOutFile(outFileName));
    String title = "Final Type Oracle Types";
    addStandardHtmlProlog(outFile, title, title, "");
    outFile.println("<p>");
    outFile.println(helpText);
    outFile.println("</p>");
    outFile.println("<pre>");
    String[] types = precompilationMetrics.getFinalTypeOracleTypes();
    Arrays.sort(types);
    for (String type : types) {
      outFile.println(type);
    }
    outFile.println("</pre>");
    addStandardHtmlEnding(outFile);
    outFile.close();
  }

  private void makeCompilerMetricsGeneratedTypes(String outFileName,
      String[] generatedTypes, String helpText) throws IOException {
    PrintWriter outFile = new PrintWriter(getOutFile(outFileName));
    String title = "Generated Types";
    addStandardHtmlProlog(outFile, title, title, "");
    outFile.println("<p>");
    outFile.println(helpText);
    outFile.println("</p>");
    outFile.println("<pre>");
    for (String type : generatedTypes) {
      outFile.println(type);
    }
    outFile.println("</pre>");
    addStandardHtmlEnding(outFile);
    outFile.close();
  }

  private void makeCompilerMetricsInitialTypeOracleTypes(String outFileName,
      ModuleMetricsArtifact moduleMetrics, String helpText) throws IOException {
    PrintWriter outFile = new PrintWriter(getOutFile(outFileName));
    String title = "Initial Type Oracle Types (built from source path)";
    addStandardHtmlProlog(outFile, title, title, "");
    outFile.println("<p>");
    outFile.println(helpText);
    outFile.println("</p>");
    outFile.println("<pre>");
    String[] types = moduleMetrics.getInitialTypes();
    Arrays.sort(types);
    for (String type : types) {
      outFile.println(type);
    }
    outFile.println("</pre>");
    addStandardHtmlEnding(outFile);
    outFile.close();
  }

  private void makeCompilerMetricsSources(String outFileName,
      ModuleMetricsArtifact moduleMetrics, String helpText) throws IOException {
    PrintWriter outFile = new PrintWriter(getOutFile(outFileName));
    String title = "Sources on Source Path";
    addStandardHtmlProlog(outFile, title, title, "");
    outFile.println("<p>");
    outFile.println(helpText);
    outFile.println("</p>");
    outFile.println("<pre>");
    String[] sources = moduleMetrics.getSourceFiles();
    Arrays.sort(sources);
    for (String source : sources) {
      outFile.println(source);
    }
    outFile.println("</pre>");
    addStandardHtmlEnding(outFile);
    outFile.close();
  }

  private void makeCompilerMetricsUnreferencedTypes(String outFileName,
      String[] unreferencedTypes, String helpText) throws IOException {
    PrintWriter outFile = new PrintWriter(getOutFile(outFileName));
    String title = "Unreferenced Types";
    addStandardHtmlProlog(outFile, title, title, "");
    outFile.println("<p>");
    outFile.println(helpText);
    outFile.println("</p>");
    outFile.println("<pre>");
    for (String type : unreferencedTypes) {
      outFile.println(type);
    }
    outFile.println("</pre>");
    addStandardHtmlEnding(outFile);
    outFile.close();
  }

  /**
   * Produces an HTML file that displays dependencies.
   *
   * @param depGraphName name of dependency graph
   * @param dependencies map of dependencies
   * @throws IOException
   */
  private void makeDependenciesHtml(String depGraphName,
      Map<String, String> dependencies) throws IOException {
    String curPackageName = "";

    HtmlInterner interner = new HtmlInterner();

    for (String reportMethod : dependencies.keySet()) {
      interner.intern(getPackageSubstring(reportMethod));
      interner.intern(getClassSubstring(reportMethod));
      interner.intern(getMethodSubstring(reportMethod));

      String depMethod = dependencies.get(reportMethod);
      while (depMethod != null) {
        interner.intern(getPackageSubstring(depMethod));
        interner.intern(getClassSubstring(depMethod));
        interner.intern(getMethodSubstring(depMethod));
        depMethod = dependencies.get(depMethod);
      }
    }
    interner.freeze();

    // Write out the interned data values as a script element
    String jsFileName = "methodDependencies-" + depGraphName + "-"
        + getPermutationId() + ".js";
    PrintWriter outFile = new PrintWriter(getOutFile(jsFileName));
    interner.printInternedDataAsJs(outFile);
    outFile.close();

    List<String> classesInPackage = new ArrayList<String>();
    for (String method : dependencies.keySet()) {
      classesInPackage.add(method);
    }
    makeDependenciesInternedHtml(depGraphName, 
        classesInPackage, dependencies, interner, jsFileName);
  }

  /**
   * Produces an HTML file that displays dependencies.
   *
   * @param depGraphName name of dependency graph
   * @param dependencies map of dependencies
   * @throws IOException
   */
  private void makeDependenciesInternedHtml(String depGraphName,
      List<String> classesInSplitPoint,
      Map<String, String> dependencies, HtmlInterner interner, String jsFileName)
      throws IOException {
    String depGraphDescription = inferDepGraphDescription(depGraphName);
    PrintWriter outFile = null;
    String curClassName = "";

    String outFileName = dependenciesFileName(depGraphName);
    outFile = new PrintWriter(getOutFile(outFileName));
    
    addStandardHtmlProlog(outFile, "Method Dependencies for "
        + depGraphDescription,
        "Method Dependencies for " + depGraphDescription, null);

    outFile.print("<script src=\"" + jsFileName
        + "\" language=\"javascript\" ></script>");

    // Write out the HTML
    outFile.print("<script>");
    for (String method : classesInSplitPoint) {
      // this key set is already in alphabetical order
      // get the package of this method, i.e., everything up to .[A-Z]

      String className = method.replaceAll("::.*", "");
      String depMethod = dependencies.get(method);
      if (curClassName.compareTo(className) != 0) {
        curClassName = className;
        if (method != classesInSplitPoint.get(0)) {
          outFile.print("j();"); // close the previous table if not the first
        }
        interner.printDependencyClassHeader(outFile, className);
      }
      interner.printDependency(outFile, dependencies, method, depMethod);
    }
    outFile.println("</script>");

    addStandardHtmlEnding(outFile);
    outFile.close();
  }

  /**
   * Produces an HTML file that shows information about a package.
   *
   * @param breakdown
   * @return the name of the HTML file
   */
  private String makePackageHtml(SizeBreakdown breakdown) throws IOException {
    String outFileName = breakdown.getId() + "-" + getPermutationId() + "-"
        + "packageBreakdown.html";
    Map<String, Integer> packageToPartialSize = breakdown.packageToSize;
    TreeMap<Integer, Set<String>> sortedPackages = new TreeMap<Integer, Set<String>>(
        Collections.reverseOrder());
    float sumSize = 0f;
    for (String packageName : packageToPartialSize.keySet()) {
      Integer curSize = packageToPartialSize.get(packageName);
      if (sortedPackages.containsKey(curSize)) {
        Set<String> existingSet = sortedPackages.get(curSize);
        existingSet.add(packageName);
        sortedPackages.put(curSize, existingSet);
      } else {
        Set<String> newSet = new TreeSet<String>();
        newSet.add(packageName);
        sortedPackages.put(curSize, newSet);
      }
      sumSize += curSize;
    }

    final PrintWriter outFile = new PrintWriter(getOutFile(outFileName));
    addSmallHtmlProlog(outFile, "Package breakdown");
    outFile.println("<body class=\"soyc-breakdown\">");
    outFile.println("<div class=\"g-doc\">");

    outFile.println("<table class=\"soyc-table\">");
    outFile.println("<colgroup>");
    outFile.println("<col id=\"soyc-splitpoint-type-col\">");
    outFile.println("<col id=\"soyc-splitpoint-size-col\">");
    outFile.println("</colgroup>");
    outFile.println("<thead>");
    outFile.println("<th>Packages (Sorted by size)</th>");
    outFile.println("<th></th>");
    outFile.println("<th class=\"soyc-numerical-col-header\">");
    outFile.println("Size <span class=\"soyc-th-units\">(Bytes)</span>");
    outFile.println("</th>");
    outFile.println("<th class=\"soyc-numerical-col-header\">% of total</th>");
    outFile.println("</thead>");
    
    NumberFormat bytesFormatter = NumberFormat.getInstance();
    bytesFormatter.setGroupingUsed(true);
    
    NumberFormat percentFormatter = NumberFormat.getPercentInstance();
    percentFormatter.setMinimumFractionDigits(1);
    percentFormatter.setMaximumFractionDigits(1);

    for (int size : sortedPackages.keySet()) {
      if (size == 0) {
        continue;
      }
      Set<String> packageNames = sortedPackages.get(size);
      for (String packageName : packageNames) {
        String drillDownFileName = classesInPackageFileName(breakdown,
            getPermutationId())
            + "#" + hashedFilenameFragment(packageName);
        float perc = size / sumSize;
        outFile.println("<tr>");
        outFile.println("<td><a href=\"" + drillDownFileName
            + "\" target=\"_top\">" + packageName + "</a></td>");
        outFile.println("<td class=\"soyc-bargraph-col\">");
        outFile.println("<div class=\"soyc-bar-graph goog-inline-block\">");
        // CHECKSTYLE_OFF
        outFile.println("<div style=\"width:" + (perc * 100.0)
            + "%;\" class=\"soyc-bar-graph-fill goog-inline-block\"></div>");
        // CHECKSTYLE_ON
        outFile.println("</div>");
        outFile.println("</td>");
        outFile.println("<td class=\"soyc-numerical-col\">");
        outFile.println(bytesFormatter.format(size));
        outFile.println("</td>");
        outFile.println("<td class=\"soyc-percent-col\">" + 
            percentFormatter.format(perc) + "</td>");
        outFile.println("</tr>");
      }
    }

    outFile.println("</table>");
    addStandardHtmlEnding(outFile);
    outFile.close();
    return outFileName;
  }

  /**
   * Find which split points include code belonging to <code>className</code>.
   */
  private Iterable<Integer> splitPointsWithClass(String className) {
    List<Integer> sps = new ArrayList<Integer>();
    for (int sp = 1; sp <= globalInformation.getNumFragments(); sp++) {
      Map<String, Integer> classToSize = globalInformation.fragmentCodeBreakdown(sp).classToSize;
      if (classToSize.containsKey(className)) {
        sps.add(sp);
      }
    }
    return sps;
  }

  private String splitStatusFileName() {
    return "splitStatus-" + getPermutationId() + ".html";
  }
}
