/*
 * 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.dev.util.StringInterner;
import com.google.gwt.soyc.MakeTopLevelHtmlForPerm.DependencyLinker;
import com.google.gwt.soyc.MakeTopLevelHtmlForPerm.NullDependencyLinker;
import com.google.gwt.soyc.io.FileSystemOutputDirectory;
import com.google.gwt.soyc.io.OutputDirectory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.zip.GZIPInputStream;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

/**
 * The command-line entry point for creating a compile report.
 */
public class SoycDashboard {
  private static class FormatException extends RuntimeException {
    public FormatException() {
      super();
    }

    public FormatException(String message) {
      super(message);
    }

    public FormatException(Throwable cause) {
      super(cause);
    }
  }

  public static void main(final String[] args) throws InterruptedException {

    System.out.println("WARNING: The direct use of the SoycDashboard is deprecated and will be removed. " +
      "The preferred usage is to invoke the compiler with the -compileReport option, which " +
      "writes the compile report directly to the extra directory.");
    Thread.currentThread();
    Thread.sleep(5000);

    Settings settings;
    try {
      settings = Settings.fromArgumentList(args);
    } catch (Settings.ArgumentListException e) {
      System.err.println(e.getMessage());
      System.err.println("Usage: "
          + "java com.google.gwt.soyc.SoycDashboard -resources dir -soycDir dir -symbolMaps dir [-out dir]");
      System.err.println("(Legacy usage: "
          + "java com.google.gwt.soyc.SoycDashboard options stories0.xml[.gz] [dependencies0.xml[.gz]] [splitpoints0.xml[.gz]])");
      System.err.println("Options:");
      System.err.println(Settings.settingsHelp());
      System.exit(1);
      return; // not reached
    }

    System.out.println("Generating the Story of Your Compile...");

    OutputDirectory outDir = new FileSystemOutputDirectory(new File(
        settings.out.get()));

    try {
      Map<String, List<String>> permInfo = readPermutationInfo(settings);
      SoycDashboard dashboard = new SoycDashboard(outDir);
      for (String permutationId : permInfo.keySet()) {
        dashboard.startNewPermutation(permutationId);
        if (settings.symbolMapsDir.get() == null) {
          dashboard.readFromFilesNamed(settings.storiesFileName,
              settings.depFileName, settings.splitPointsFileName);
        } else {
          String soycDir = settings.soycDir.get();
          dashboard.readFromFilesNamed(soycInputFile(soycDir, "stories",
              permutationId), soycInputFile(soycDir, "dependencies",
              permutationId), soycInputFile(soycDir, "splitPoints",
              permutationId));
        }
        dashboard.generateForOnePermutation();
        System.out.println("Finished creating reports for permutation.");
      }

      dashboard.generateCrossPermutationFiles(permInfo);
      System.out.println("Finished creating reports. To see the dashboard, open index.html in your browser.");
    } catch (ParserConfigurationException e) {
      System.err.println("Could not parse document. " + e.getMessage());
      System.exit(1);
    } catch (SAXException e) {
      System.err.println("Could not create SAX parser. " + e.getMessage());
      System.exit(1);
    } catch (FileNotFoundException e) {
      System.err.println("Cannot open file " + e.getMessage());
      System.exit(1);
    } catch (IOException e) {
      System.err.println("Error creating html file. " + e.getMessage());
      System.exit(1);
    }
  }

  /**
   * Open a file for reading. If the filename ends in .gz, then wrap the stream
   * with a {@link GZIPInputStream}.
   */
  public static InputStream openPossiblyGzippedFile(String filename)
      throws IOException {
    InputStream in = new FileInputStream(filename);
    if (filename.endsWith(".gz")) {
      in = new GZIPInputStream(in);
    }
    in = new BufferedInputStream(in);
    return in;
  }

  /*
   * cleans up the RPC code categories
   */
  private static void foldInRPCHeuristic(
      final HashMap<String, CodeCollection> nameToCodeColl) {
    /**
     * Heuristic: this moves all classes that override serializable from RPC to
     * "Other Code" *if* there is no RPC generated code, i.e., if the
     * application really is not using RPC
     */

    if (nameToCodeColl.get("rpcGen").classes.size() == 0) {

      for (String className : nameToCodeColl.get("rpcUser").classes) {

        if ((!nameToCodeColl.get("widget").classes.contains(className))
            && (!nameToCodeColl.get("jre").classes.contains(className))
            && (!nameToCodeColl.get("gwtLang").classes.contains(className))) {
          nameToCodeColl.get("allOther").classes.add(className);
        }
      }
      nameToCodeColl.get("rpcUser").classes.clear();

      for (String className : nameToCodeColl.get("rpcGwt").classes) {
        if ((!nameToCodeColl.get("widget").classes.contains(className))
            && (!nameToCodeColl.get("jre").classes.contains(className))
            && (!nameToCodeColl.get("gwtLang").classes.contains(className))) {
          nameToCodeColl.get("allOther").classes.add(className);
        }
      }
      nameToCodeColl.get("rpcGwt").classes.clear();
    }
  }

  private static DefaultHandler parseXMLDocumentDependencies(
      final Map<String, Map<String, String>> allDependencies) {
    DefaultHandler handler = new DefaultHandler() {

      // may want to create a class for this later
      String curMethod;
      Map<String, String> dependencies = new TreeMap<String, String>();
      String graphExtends = null;
      StringBuilder valueBuilder = new StringBuilder();

      @Override
      public void endElement(String uri, String localName, String qName) {
        if (localName.compareTo("table") == 0) {
          if (graphExtends != null) {
            // Add in elements from the extended graph
            for (Entry<String, String> entry : allDependencies.get(graphExtends).entrySet()) {
              dependencies.put(entry.getKey(), entry.getValue());
            }
          }
        }
      }

      @Override
      public void startElement(String nsUri, String strippedName,
          String tagName, final Attributes attributes) {

        valueBuilder.delete(0, valueBuilder.length());

        if (strippedName.compareTo("table") == 0
            && (attributes.getValue("name") != null)) {
          String name = attributes.getValue("name");
          dependencies = new TreeMap<String, String>();
          allDependencies.put(StringInterner.get().intern(name), dependencies);
          if (attributes.getValue("extends") != null) {
            graphExtends = StringInterner.get().intern(attributes.getValue("extends"));
            if (!allDependencies.containsKey(graphExtends)) {
              throw new FormatException("Graph " + name
                  + " extends an unknown graph " + graphExtends);
            }
          } else {
            graphExtends = null;
          }
        } else if ((strippedName.compareTo("method") == 0)
            && (attributes.getValue("name") != null)) {
          curMethod = StringInterner.get().intern(attributes.getValue("name"));
        } else if ((strippedName.compareTo("called") == 0)
            && (attributes.getValue("by") != null)) {
          String curDepMethod = attributes.getValue("by");
          if (!dependencies.containsKey(curMethod)) {
            dependencies.put(StringInterner.get().intern(curMethod),
                StringInterner.get().intern(curDepMethod));
          }
        }
      }
    };
    return handler;
  }

  private static Map<String, List<String>> readPermutationInfo(Settings settings)
      throws FileNotFoundException {
    Map<String, List<String>> allPermsInfo = new TreeMap<String, List<String>>();
    if (settings.symbolMapsDir.get() == null) {
      String permutationId = settings.storiesFileName;
      permutationId = permutationId.replaceAll(".*/stories", "");
      permutationId = permutationId.replaceAll("\\.xml(\\.gz)?", "");
    } else {
      File dir = new File(settings.symbolMapsDir.get());
      String files[] = dir.list();
      for (Integer i = 0; i < files.length; i++) {
        String permFileName = settings.symbolMapsDir.get() + "/" + files[i];
        FileReader fir = new FileReader(permFileName);

        Scanner sc = new Scanner(fir);

        String permutationId = "";
        String permutationInfo = "";
        List<String> permutationInfoList = new ArrayList<String>();
        boolean firstLine = true;
        String curLine = sc.nextLine();
        curLine = curLine.trim();
        while (curLine.startsWith("# {")) {

            curLine = curLine.replace("# {", "");
            curLine = curLine.replace("}", "");
            curLine = curLine.trim();
            if (firstLine) {
              permutationId = curLine;
              firstLine = false;
            } else {
              if (permutationInfo.length() > 0) {
                permutationInfo += "<br>";
              }
              permutationInfo += curLine;
              permutationInfoList.add(curLine);
            }
            if (sc.hasNextLine()) {
              curLine = sc.nextLine();
              curLine = curLine.trim();
            }
        }
        allPermsInfo.put(permutationId, permutationInfoList);
      }
    }
    return allPermsInfo;
  }

  private static String soycInputFile(String soycDir, String baseName,
      String permutationId) {
    String name = soycDir + "/" + baseName + permutationId + ".xml.gz";
    if (new File(name).exists()) {
      return name;
    }
    return soycDir + "/" + baseName + permutationId + ".xml";
  }

  /**
   * Global information for the current permutation being emitted.
   */
  private GlobalInformation globalInformation;

  /**
   * HTML emitter for the current permutation being emitted.
   */
  private MakeTopLevelHtmlForPerm makeTopLevelHtmlForPerm;

  private final OutputDirectory outDir;

  public SoycDashboard(OutputDirectory outDir) {
    this.outDir = outDir;
  }

  public void generateCompilerMetricsForOnePermuation(
      ModuleMetricsArtifact moduleMetrics,
      PrecompilationMetricsArtifact precompilationMetrics,
      CompilationMetricsArtifact compilationMetrics)  throws IOException {
    makeTopLevelHtmlForPerm.makeCompilerMetricsPermFiles(moduleMetrics,
        precompilationMetrics, compilationMetrics);
  }

  public void generateCrossPermutationFiles(Map<String, List<String>> permInfo)
      throws IOException {
    StaticResources.emit(outDir);
    MakeTopLevelHtmlForPerm.makeTopLevelHtmlForAllPerms(permInfo, outDir);
  }

  public void generateForOnePermutation() throws IOException {
    if (globalInformation.dependencies != null) {
      makeTopLevelHtmlForPerm.makeDependenciesHtml();
    }

    if (globalInformation.getNumFragments() > 0) {
      makeTopLevelHtmlForPerm.makeSplitStatusPages();
      makeTopLevelHtmlForPerm.makeLeftoverStatusPages();
    }
    for (SizeBreakdown breakdown : globalInformation.allSizeBreakdowns()) {
      DependencyLinker linker = chooseDependencyLinker(breakdown);
      makeHTMLFiles(makeTopLevelHtmlForPerm, breakdown, linker);
    }
  }

  public void readDependencies(InputStream stream)
      throws ParserConfigurationException, SAXException, IOException {
    globalInformation.dependencies = new TreeMap<String, Map<String, String>>();
    DefaultHandler depHandler = parseXMLDocumentDependencies(globalInformation.dependencies);
    SAXParserFactory depFactoryMain = SAXParserFactory.newInstance();
    depFactoryMain.setNamespaceAware(true);
    SAXParser saxParser = depFactoryMain.newSAXParser();
    saxParser.parse(stream, depHandler);
  }

  public void readSizeMaps(InputStream stream)
      throws ParserConfigurationException, SAXException, IOException {
    DefaultHandler handler = parseXMLDocumentSizeMap(globalInformation);
    SAXParserFactory factoryMain = SAXParserFactory.newInstance();
    factoryMain.setNamespaceAware(true);
    SAXParser saxParser = factoryMain.newSAXParser();
    saxParser.parse(stream, handler);

    // Now clean up the information that has been read in various ways
    globalInformation.computePackageSizes();

    // add to "All Other Code" if none of the special categories apply
    for (SizeBreakdown breakdown : globalInformation.allSizeBreakdowns()) {
      updateAllOtherCodeType(breakdown.nameToCodeColl);
    }

    // clean up the RPC categories
    for (SizeBreakdown breakdown : globalInformation.allSizeBreakdowns()) {
      foldInRPCHeuristic(breakdown.nameToCodeColl);
    }
  }

  public void readSplitPoints(InputStream stream)
      throws ParserConfigurationException, SAXException, IOException {
    DefaultHandler splitPointHandler = parseXMLDocumentSplitPoints();
    SAXParserFactory splitPointsFactoryMain = SAXParserFactory.newInstance();
    splitPointsFactoryMain.setNamespaceAware(true);

    SAXParser saxParser = splitPointsFactoryMain.newSAXParser();
    saxParser.parse(stream, splitPointHandler);
  }

  public void startNewPermutation(String permutationId) {
    globalInformation = new GlobalInformation(permutationId);
    makeTopLevelHtmlForPerm = new MakeTopLevelHtmlForPerm(globalInformation,
        outDir);
  }

  private Collection<SizeBreakdown> breakdownsForFragment(Integer fragment) {
    List<SizeBreakdown> breakdowns = new ArrayList<SizeBreakdown>();
    breakdowns.add(globalInformation.getTotalCodeBreakdown());
    if (fragment == 0) {
      breakdowns.add(globalInformation.getInitialCodeBreakdown());
    }
    if (fragment == (globalInformation.getNumFragments() + 1)) {
      breakdowns.add(globalInformation.getLeftoversBreakdown());
    }
    if (fragment >= 1 && fragment <= globalInformation.getNumFragments()) {
      breakdowns.add(globalInformation.fragmentCodeBreakdown(fragment));
    }
    return breakdowns;
  }

  private DependencyLinker chooseDependencyLinker(SizeBreakdown breakdown) {
    if (globalInformation.dependencies == null) {
      // no dependencies are available
      return new NullDependencyLinker();
    }

    if (breakdown == globalInformation.getTotalCodeBreakdown()) {
      if (globalInformation.getNumFragments() > 0) {
        return makeTopLevelHtmlForPerm.new DependencyLinkerForTotalBreakdown();
      } else {
        return makeTopLevelHtmlForPerm.new DependencyLinkerForInitialCode();
      }
    } else if (breakdown == globalInformation.getInitialCodeBreakdown()) {
      return makeTopLevelHtmlForPerm.new DependencyLinkerForInitialCode();
    } else if (breakdown == globalInformation.getLeftoversBreakdown()) {
      assert globalInformation.getNumFragments() > 0;
      return makeTopLevelHtmlForPerm.new DependencyLinkerForLeftoversFragment();
    } else {
      return new NullDependencyLinker();
    }
  }

  /**
   * Generates all the HTML files for one size breakdown.
   */
  private void makeHTMLFiles(MakeTopLevelHtmlForPerm makeTopLevelHtmlForPerm,
      SizeBreakdown breakdown, DependencyLinker depLinker) throws IOException {
    makeTopLevelHtmlForPerm.makePackageClassesHtmls(breakdown, depLinker);
    makeTopLevelHtmlForPerm.makeCodeTypeClassesHtmls(breakdown);
    makeTopLevelHtmlForPerm.makeLiteralsClassesTableHtmls(breakdown);
    makeTopLevelHtmlForPerm.makeBreakdownShell(breakdown);
    makeTopLevelHtmlForPerm.makeTopLevelShell();
  }

  private DefaultHandler parseXMLDocumentSizeMap(
      final GlobalInformation globalInformation) {
    return new DefaultHandler() {
      int fragment = -1;

      @Override
      public void endElement(String uri, String localName, String qName) {
        if (localName.compareTo("sizemap") == 0) {
          fragment = -1;
        }
      }

      @Override
      public void startElement(String uri, String localName, String qName,
          final Attributes attributes) {
        if (localName.compareTo("sizemap") == 0) {
          // starting a new size map
          String fragString = attributes.getValue("fragment");
          if (fragString == null) {
            throw new FormatException();
          }
          try {
            fragment = Integer.valueOf(fragString);
          } catch (NumberFormatException e) {
            throw new FormatException(e);
          }
          String sizeString = attributes.getValue("size");
          if (sizeString == null) {
            throw new FormatException();
          }
          int size;
          try {
            size = Integer.valueOf(sizeString);
          } catch (NumberFormatException e) {
            throw new FormatException(e);
          }
          for (SizeBreakdown breakdown : breakdownsForFragment(fragment)) {
            breakdown.sizeAllCode += size;
          }
        } else if (localName.compareTo("size") == 0) {
          String type = attributes.getValue("type");
          if (type == null) {
            throw new FormatException();
          }
          String ref = attributes.getValue("ref");
          if (ref == null) {
            throw new FormatException();
          }
          String sizeString = attributes.getValue("size");
          if (sizeString == null) {
            throw new FormatException();
          }
          int size;
          try {
            size = Integer.valueOf(sizeString);
          } catch (NumberFormatException e) {
            throw new FormatException(e);
          }
          recordSize(type, ref, size, globalInformation);
        }
      }

      private void accountForSize(SizeBreakdown breakdown, String refType,
          String ref, int size, GlobalInformation globalInformation) {
        if (refType.equals("string")) {
          LiteralsCollection stringLiterals = breakdown.nameToLitColl.get("string");
          stringLiterals.size += size;
          stringLiterals.literals.add(ref);
        } else if (refType.equals("var")) {
          // Nothing to record, because no breakdown is provided for random
          // variables
        } else {
          if (!refType.equals("type") && !refType.equals("method") && !refType.equals("field")) {
            throw new FormatException();
          }
          
          if (refType.equals("method")) {
            breakdown.methodToSize.put(ref, Integer.valueOf(size));
          }
          
          String className = ref;
          if (className.contains("::")) {
            /*
             * It's a method or field reference. Discard the method/field part.
             */
            int idx = className.indexOf(':');
            className = className.substring(0, idx);
          }
          className = StringInterner.get().intern(className);
          // derive the package name from the class
          String packageName;
          if (!globalInformation.getClassToPackage().containsKey(className)) {
            packageName = className;
            packageName = packageName.replaceAll("\\.[A-Z].*", "");
            globalInformation.getClassToPackage().put(className, packageName);
          } else {
            packageName = globalInformation.getClassToPackage().get(className);
          }

          if (!globalInformation.getPackageToClasses().containsKey(packageName)) {
            TreeSet<String> insertSet = new TreeSet<String>();
            insertSet.add(className);
            globalInformation.getPackageToClasses().put(packageName, insertSet);
          } else {
            globalInformation.getPackageToClasses().get(packageName).add(
                className);
          }

          recordClassCategories(breakdown.nameToCodeColl, className,
              packageName);

          if (breakdown.classToSize.containsKey(className)) {
            int newSize = breakdown.classToSize.get(className) + size;
            breakdown.classToSize.put(className, newSize);
          } else {
            breakdown.classToSize.put(className, size);
          }
        }
      }

      private void recordClassCategories(
          final HashMap<String, CodeCollection> nameToCodeColl,
          String className, String packageName) {
        if (packageName.startsWith("java")) {
          nameToCodeColl.get("jre").classes.add(className);
        } else if (packageName.startsWith("com.google.gwt.lang")) {
          nameToCodeColl.get("gwtLang").classes.add(className);
        }
        if (className.contains("_CustomFieldSerializer")) {
          nameToCodeColl.get("rpcUser").classes.add(className);
        } else if (className.endsWith("_FieldSerializer")
            || className.endsWith("_Proxy")
            || className.endsWith("_TypeSerializer")) {
          nameToCodeColl.get("rpcGen").classes.add(className);
        }
      }

      private void recordSize(String refType, String ref, int size,
          GlobalInformation globalInformation) {
        refType = StringInterner.get().intern(refType);
        ref = StringInterner.get().intern(ref);
        for (SizeBreakdown breakdown : breakdownsForFragment(fragment)) {
          accountForSize(breakdown, refType, ref, size, globalInformation);
        }
      }
    };
  }

  private DefaultHandler parseXMLDocumentSplitPoints() {
    DefaultHandler handler = new DefaultHandler() {

      private boolean inInitialLoadSequence = false;

      @Override
      public void endElement(String uri, String localName, String qName) {
        if (localName.compareTo("initialesq") == 0) {
          inInitialLoadSequence = false;
        }
      }

      @Override
      public void startElement(String nsUri, String strippedName,
          String tagName, final Attributes attributes) {
        if (strippedName.compareTo("splitpoint") == 0) {
          parseSplitPoint(attributes);
        } else if (strippedName.compareTo("initialseq") == 0) {
          inInitialLoadSequence = true;
        } else if (inInitialLoadSequence
            && strippedName.compareTo("splitpointref") == 0) {
          globalInformation.getInitialFragmentLoadSequence().add(
              parseSplitPointReference(attributes));
        }
      }

      /**
       * Parses a split point entry from a splitpoints XML soyc file.
       * A split point node as in \<splitpoint id=N location=DESC/\>
       *
       * @param attributes the attributes of the splitpoint node (provided by the SAX parsing
       *                   infrastructure)
       */
      private void parseSplitPoint(final Attributes attributes) {
        if (attributes.getValue("id") != null) {
          String curSplitPoint = attributes.getValue("id");
          if (attributes.getValue("location") != null) {
            String curSplitPointLocation = attributes.getValue("location");

            curSplitPointLocation = curSplitPointLocation.replaceAll("\\(L.*",
                "");

            globalInformation.addFragmentDescriptor(
                Integer.parseInt(curSplitPoint), curSplitPointLocation);
          }
        }
      }

      private Integer parseSplitPointReference(final Attributes attributes) {
        String spString = attributes.getValue("id");
        if (spString == null) {
          throw new FormatException("Could not parse split point reference");
        }
        return Integer.valueOf(spString);
      }

    };
    return handler;
  }

  private void readFromFilesNamed(String storiesFileName,
      String dependenciesFileName, String splitPointsFileName)
      throws ParserConfigurationException, SAXException, IOException {
    if (dependenciesFileName != null && new File(dependenciesFileName).exists()) {
      readDependencies(openPossiblyGzippedFile(dependenciesFileName));
    }

    if (splitPointsFileName != null && new File(splitPointsFileName).exists()) {
      readSplitPoints(openPossiblyGzippedFile(splitPointsFileName));
    }

    readSizeMaps(openPossiblyGzippedFile(storiesFileName));
  }

  /*
   * assigns code to "all other code" if none of the special categories apply
   */
  private void updateAllOtherCodeType(
      final HashMap<String, CodeCollection> nameToCodeColl) {
    // all classes not in any of the other categories
    for (String className : globalInformation.getClassToPackage().keySet()) {
      if ((!nameToCodeColl.get("widget").classes.contains(className))
          && (!nameToCodeColl.get("rpcUser").classes.contains(className))
          && (!nameToCodeColl.get("rpcGwt").classes.contains(className))
          && (!nameToCodeColl.get("rpcGen").classes.contains(className))
          && (!nameToCodeColl.get("jre").classes.contains(className))
          && (!nameToCodeColl.get("gwtLang").classes.contains(className))) {
        nameToCodeColl.get("allOther").classes.add(className);
      }
    }
  }
}
