/*
 * 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 java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
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.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 {
    public String dependencyLinkForClass(String className) {
      String packageName = globalInformation.getClassToPackage().get(className);
      assert packageName != null;
      return dependenciesFileName("initial", packageName) + "#" + className;
    }
  }

  /**
   * A dependency linker for the leftovers fragment. It links to leftovers
   * status pages.
   */
  public class DependencyLinkerForLeftoversFragment implements DependencyLinker {
    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 {
    public String dependencyLinkForClass(String className) {
      return splitStatusFileName() + "#" + hashedFilenameFragment(className);
    }
  }

  /**
   * A dependency linker that never links to anything.
   */
  public static class NullDependencyLinker implements DependencyLinker {
    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 sp = 1; sp <= globalInformation.getNumSplitPoints(); sp++) {
        outFile.println("        '"
            + globalInformation.getSplitPointToLocation().get(sp) + "',");
      }
      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(\"<a name='\" + className + \"'>\");");
      outFile.println("    document.write(\"<h3 class='soyc-class-header'>Class: \" + className + "
          + "\"</a></h3>\");");
      outFile.println("  }");

      // function to print a single dependency in the methodDependencies report
      // see printDependency()
      outFile.println("  function b(c, deps) {");
      outFile.println("    document.write(\"<div class='main'>"
          + "<a class='toggle soyc-call-stack-link' onclick='toggle.call(this)'>\");");
      outFile.println("    document.write(\"<span class='calledBy'> Call stack: </span>\");");
      outFile.println("    document.write(internedStrings[c[0]] + \".\" + internedStrings[c[1]] + "
          + "\"::\" + internedStrings[c[2]] + \"</a>\");");
      outFile.println("    document.write(\"<ul 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></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-' + internedStrings[packageHashRef] "
          + "+ '-" + 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.getNumSplitPoints() + "; sp++) {");
      outFile.println("      var d2 = 'methodDependencies-sp' + sp + '-' + "
          + "internedStrings[packageHashRef] + '-" + 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 static String escapeXml(String unescaped) {
    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>Size <span class=\"soyc-th-units\">(Bytes)</span></th>");
      outFile.println("</thead>");

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

  public void makeCompilerMetricsPermFiles(ModuleMetricsArtifact moduleMetrics,
      PrecompilationMetricsArtifact precompilationMetrics,
      CompilationMetricsArtifact compilationMetrics) throws IOException {
    String outFileName = "CompilerMetrics-"
        + precompilationMetrics.getPermuationBase() + "-index.html";
    PrintWriter outFile = new PrintWriter(getOutFile(outFileName));
    String title = "Compiler Metrics for Permutation "
        + compilationMetrics.getPermuationId();
    addStandardHtmlProlog(outFile, title, title, "Build Time Metrics");

    outFile.println("<div id=\"bd\">");
    int permutationId = compilationMetrics.getPermuationId();

    // 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>Elapsed Time</th>");
    outFile.println("</thead>");

    outFile.println("<tr>");
    outFile.println("<td>");
    outFile.println("Module Analysis");
    outFile.println("</td>");
    outFile.println("<td>" + moduleMetrics.getElapsedMilliseconds() + " ms");
    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>" + precompilationMetrics.getElapsedMilliseconds()
        + " ms");
    outFile.println("</td>");
    outFile.println("</tr>");

    outFile.println("<tr>");
    outFile.println("<td>");
    outFile.println("Compile");
    outFile.println("</td>");
    outFile.println("<td>" + compilationMetrics.getElapsedMilliseconds()
        + " ms");
    outFile.println("</td>");
    outFile.println("</tr>");
    outFile.println("</table>");

    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>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>");
    outFile.println("" + 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>");
    outFile.println("" + 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>");
    outFile.println("" + 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>");
    outFile.println("" + 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>");
    outFile.println("" + 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>");
    outFile.println("" + 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.print("<th>Size <span class=\"soyc-th-units\">(Bytes)</span></th>");
        outFile.print("</thead>");

        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) * 100;
            outFile.println("<tr>");
            if (drillDownFileName == null) {
              outFile.println("<td>" + className + "</td>");
            } else {
              outFile.println("<td><a href=\"" + drillDownFileName
                  + "\" target=\"_top\">" + className + "</a></td>");
            }
            outFile.print("<td>");
            outFile.print("<div class=\"soyc-bar-graph goog-inline-block\">");
            // CHECKSTYLE_OFF
            outFile.print("<div style=\"width:" + perc
                + "%;\" class=\"soyc-bar-graph-fill goog-inline-block\"></div>");
            // CHECKSTYLE_ON
            outFile.print("</div>");
            outFile.print(size + " (" + formatNumber(perc) + "%)");
            outFile.print("</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, "");

    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\">"
        + 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\">"
        + 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\">"
        + 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>Size <span class=\"soyc-th-units\">(Bytes)</span></th>");
    outFile.println("</thead>");
    outFile.println("<tbody>");

    if (globalInformation.getSplitPointToLocation().size() >= 1) {

      int numSplitPoints = globalInformation.getSplitPointToLocation().size();
      int maxSize = globalInformation.getTotalCodeBreakdown().sizeAllCode;

      for (int i = FRAGMENT_NUMBER_TOTAL_PROGRAM; i <= numSplitPoints + 1; i++) {
        SizeBreakdown breakdown;
        if (i == FRAGMENT_NUMBER_TOTAL_PROGRAM) {
          continue;
        } else if (i == numSplitPoints + 1) { // leftovers
          continue;
        } else if (i == FRAGMENT_NUMBER_INITIAL_DOWNLOAD) {
          continue;
        } else {
          breakdown = globalInformation.splitPointCodeBreakdown(i);
        }

        String drillDownFileName = shellFileName(breakdown, getPermutationId());
        String splitPointDescription = globalInformation.getSplitPointToLocation().get(
            i);

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

        outFile.println("<tr>");
        outFile.println("<td>" + i + "</td>");
        outFile.println("<td><a href=\"" + drillDownFileName + "\">"
            + splitPointDescription + "</a></td>");
        outFile.println("<td>");
        outFile.println("<div class=\"soyc-bar-graph goog-inline-block\">");
        // CHECKSTYLE_OFF
        outFile.println("<div style=\"width:" + perc
            + "%;\" class=\"soyc-bar-graph-fill goog-inline-block\"></div>");
        // CHECKSTYLE_ON
        outFile.println("</div>");
        outFile.println(size + " Bytes (" + formatNumber(perc) + "%)");
        outFile.println("</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, String packageName) {
    return "methodDependencies-" + depGraphName + "-"
        + hashedFilenameFragment(packageName) + "-" + getPermutationId()
        + ".html";
  }

  /**
   * Format floating point number to two decimal points.
   *
   * @param number
   * @return formatted number
   */
  private String formatNumber(float number) {
    DecimalFormat formatBy = new DecimalFormat("#.##");
    return formatBy.format(number);
  }

  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.getSplitPointInitialLoadSequence().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>Size <span class=\"soyc-th-units\">(Bytes)</span></th>");
    outFile.println("</thead>");

    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) * 100;
        outFile.println("<tr>");
        outFile.println("<td><a href=\"" + drillDownFileName
            + "\" target=\"_top\">" + codeType + "</a></td>");
        outFile.println("<td>");
        outFile.println("<div class=\"soyc-bar-graph goog-inline-block\">");
        // CHECKSTYLE_OFF
        outFile.println("<div style=\"width:" + perc
            + "%;\" class=\"soyc-bar-graph-fill goog-inline-block\"></div>");
        // CHECKSTYLE_ON
        outFile.println("</div>");
        outFile.println(size + " (" + formatNumber(perc) + "%)");
        outFile.println("</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();

    // Separate out the packages to write them into different HTML files.
    String packageName = "";
    List<String> classesInPackage = new ArrayList<String>();
    for (String method : dependencies.keySet()) {
      // this key set is already in alphabetical order
      // get the package of this method, i.e., everything up to .[A-Z]
      packageName = method.replaceAll("\\.\\p{Upper}.*", "");

      if (curPackageName.compareTo("") == 0) {
        curPackageName = packageName;
      } else if (curPackageName.compareTo(packageName) != 0) {
        makeDependenciesInternedHtml(depGraphName, curPackageName,
            classesInPackage, dependencies, interner, jsFileName);
        classesInPackage = new ArrayList<String>();
        curPackageName = packageName;
      }
      classesInPackage.add(method);
    }
    if (classesInPackage.size() > 0) {
      makeDependenciesInternedHtml(depGraphName, curPackageName,
          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,
      String packageName, List<String> classesInPackage,
      Map<String, String> dependencies, HtmlInterner interner, String jsFileName)
      throws IOException {
    String depGraphDescription = inferDepGraphDescription(depGraphName);
    PrintWriter outFile = null;
    String curClassName = "";

    String outFileName = dependenciesFileName(depGraphName, packageName);
    outFile = new PrintWriter(getOutFile(outFileName));
    String packageDescription = packageName.length() == 0
        ? "the default package" : packageName;
    addStandardHtmlProlog(outFile, "Method Dependencies for "
        + depGraphDescription,
        "Method Dependencies for " + depGraphDescription, "Showing Package: "
            + packageDescription);

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

    // Write out the HTML
    outFile.print("<script>");
    for (String method : classesInPackage) {
      // 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;
        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>Size <span class=\"soyc-th-units\">(Bytes)</span></th>");
    outFile.println("</thead>");

    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) * 100;
        outFile.println("<tr>");
        outFile.println("<td><a href=\"" + drillDownFileName
            + "\" target=\"_top\">" + packageName + "</a></td>");
        outFile.println("<td>");
        outFile.println("<div class=\"soyc-bar-graph goog-inline-block\">");
        // CHECKSTYLE_OFF
        outFile.println("<div style=\"width:" + perc
            + "%;\" class=\"soyc-bar-graph-fill goog-inline-block\"></div>");
        // CHECKSTYLE_ON
        outFile.println("</div>");
        outFile.println(size + " (" + formatNumber(perc) + "%)");
        outFile.println("</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.getNumSplitPoints(); sp++) {
      Map<String, Integer> classToSize = globalInformation.splitPointCodeBreakdown(sp).classToSize;
      if (classToSize.containsKey(className)) {
        sps.add(sp);
      }
    }
    return sps;
  }

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