// Copyright 2015 The Bazel Authors. All rights reserved.
//
// 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.devtools.build.lib.profiler.output;

import com.google.common.base.Optional;
import com.google.devtools.build.lib.profiler.ProfilePhase;
import com.google.devtools.build.lib.profiler.ProfilerTask;
import com.google.devtools.build.lib.profiler.statistics.CriticalPathStatistics;
import com.google.devtools.build.lib.profiler.statistics.PhaseStatistics;
import com.google.devtools.build.lib.profiler.statistics.PhaseSummaryStatistics;
import com.google.devtools.build.lib.profiler.statistics.PhaseVfsStatistics;
import com.google.devtools.build.lib.profiler.statistics.PhaseVfsStatistics.Stat;
import com.google.devtools.build.lib.util.StringUtil;
import com.google.devtools.build.lib.util.TimeUtilities;

import java.io.PrintStream;
import java.util.Arrays;
import java.util.EnumMap;

import javax.annotation.Nullable;

/**
 * Output {@link PhaseSummaryStatistics}, {@link PhaseStatistics} and {@link PhaseVfsStatistics}
 * in HTML format.
 */
public final class PhaseHtml extends HtmlPrinter {

  private final PhaseSummaryStatistics phaseSummaryStats;
  private final EnumMap<ProfilePhase, PhaseStatistics> phaseStatistics;
  private final Optional<CriticalPathStatistics> criticalPathStatistics;
  private final int vfsStatsLimit;
  private final Optional<Integer> missingActionsCount;

  /**
   * @param vfsStatsLimit maximum number of VFS statistics to print, or -1 for no limit.
   */
  public PhaseHtml(
      PrintStream out,
      PhaseSummaryStatistics phaseSummaryStats,
      EnumMap<ProfilePhase, PhaseStatistics> phaseStatistics,
      Optional<CriticalPathStatistics> critPathStats,
      Optional<Integer> missingActionsCount,
      int vfsStatsLimit) {
    super(out);
    this.phaseSummaryStats = phaseSummaryStats;
    this.phaseStatistics = phaseStatistics;
    this.criticalPathStatistics = critPathStats;
    this.missingActionsCount = missingActionsCount;
    this.vfsStatsLimit = vfsStatsLimit;
  }

  public PhaseHtml(
      PrintStream out,
      PhaseSummaryStatistics summaryStatistics,
      EnumMap<ProfilePhase, PhaseStatistics> summaryPhaseStatistics,
      int vfsStatsLimit) {
    this(
        out,
        summaryStatistics,
        summaryPhaseStatistics,
        Optional.<CriticalPathStatistics>absent(),
        Optional.<Integer>absent(),
        vfsStatsLimit);
  }

  /**
   * Output a style tag with all necessary CSS directives
   */
  public void printCss() {
    lnPrint("<style type=\"text/css\"><!--");
    down();
    lnPrint("div.phase-statistics {");
    lnPrint("  margin: 0 10;");
    lnPrint("  font-size: small;");
    lnPrint("  font-family: monospace;");
    lnPrint("  float: left;");
    lnPrint("}");
    lnPrint("table.phase-statistics {");
    lnPrint("  border: 0px; text-align: right;");
    lnPrint("}");
    lnPrint("table.phase-statistics td {");
    lnPrint("  padding: 0 5;");
    lnPrint("}");
    lnPrint("td.left {");
    lnPrint("  text-align: left;");
    lnPrint("}");
    lnPrint("td.center {");
    lnPrint("  text-align: center;");
    lnPrint("}");
    up();
    lnPrint("--></style>");
  }

  /**
   * Print tables from {@link #phaseSummaryStats} and {@link #phaseStatistics} side by side.
   */
  public void print() {
    printPhaseSummaryStatistics();

    for (ProfilePhase phase :
        Arrays.asList(ProfilePhase.INIT, ProfilePhase.LOAD, ProfilePhase.ANALYZE)) {
      PhaseStatistics statistics = phaseStatistics.get(phase);
      if (statistics == null || !statistics.wasExecuted()) {
        continue;
      }
      printPhaseStatistics(statistics);
    }
    printExecutionPhaseStatistics();
    lnElement("div", "style", "clear: both;");
  }

  /**
   * Print header and tables for a single phase.
   */
  private void printPhaseStatistics(PhaseStatistics phaseStat) {
    printPhaseHead(phaseStat);
    printTwoColumnStatistic(
        String.format("Total %s time", phaseStat.getProfilePhase().nick),
        phaseStat.getPhaseDurationNanos());

    printTimingDistribution(phaseStat);
    lnClose(); // table
    printVfsStatistics(phaseStat.getVfsStatistics());
    lnClose(); // div
  }

  private void printPhaseHead(PhaseStatistics phaseStat) {
    lnOpen("div", "class", "phase-statistics");
    lnElement(
        "h3",
        String.format(
            "%s Phase Information", StringUtil.capitalize(phaseStat.getProfilePhase().nick)));
    lnOpen("table", "class", "phase-statistics");
  }

  private void printExecutionPhaseStatistics() {
    PhaseStatistics execPhase = phaseStatistics.get(ProfilePhase.EXECUTE);
    if (execPhase == null || !execPhase.wasExecuted()) {
      return;
    }
    printPhaseHead(execPhase);
    for (PhaseStatistics phaseStat :
        Arrays.asList(
            phaseStatistics.get(ProfilePhase.PREPARE),
            execPhase,
            phaseStatistics.get(ProfilePhase.FINISH))) {
      if (phaseStat.wasExecuted()) {
        printTwoColumnStatistic(
            String.format("Total %s time", phaseStat.getProfilePhase().nick),
            phaseStat.getPhaseDurationNanos());
      }
    }

    long execTime = execPhase.getPhaseDurationNanos();

    printTwoColumnStatistic("Actual execution time", execTime);

    CriticalPathHtml criticalPaths = null;
    if (criticalPathStatistics.isPresent()) {
      criticalPaths = new CriticalPathHtml(out, criticalPathStatistics.get(), execTime);
      criticalPaths.printTimingBreakdown();
    }

    printTimingDistribution(execPhase);
    lnClose(); // table opened by printPhaseHead

    if (criticalPathStatistics.isPresent()) {
      criticalPaths.printCriticalPaths();
    }

    if (missingActionsCount.isPresent() && missingActionsCount.get() > 0) {
      lnOpen("p");
      lnPrint(missingActionsCount.get());
      print(
          " action(s) are present in the"
              + " action graph but missing instrumentation data. Most likely the profile file"
              + " has been created during a failed or aborted build.");
      lnClose();
    }

    printVfsStatistics(execPhase.getVfsStatistics());
    lnClose(); // div
  }

  /**
   * Print the table rows for the {@link ProfilerTask} types and their execution times.
   */
  private void printTimingDistribution(PhaseStatistics phaseStat) {
    if (!phaseStat.isEmpty()) {
      lnOpen("tr");
      element("td", "class", "left", "colspan", "4", "Total time (across all threads) spent on:");
      close(); // tr
      lnOpen("tr");
      element("th", "Type");
      element("th", "Total");
      element("th", "Count");
      element("th", "Average");
      close(); // tr
      for (ProfilerTask taskType : phaseStat) {
        lnOpen("tr", "class", "phase-task-statistics");
        element("td", taskType);
        element("td", prettyPercentage(phaseStat.getTotalRelativeDuration(taskType)));
        element("td", phaseStat.getCount(taskType));
        element("td", TimeUtilities.prettyTime(phaseStat.getMeanDuration(taskType)));
        close(); // tr
      }
    }
  }

  /**
   * Print the time spent on VFS operations on each path. Output is grouped by operation and sorted
   * by descending duration. If multiple of the same VFS operation were logged for the same path,
   * print the total duration.
   */
  private void printVfsStatistics(@Nullable PhaseVfsStatistics stats) {
    if (vfsStatsLimit == 0 || stats == null || stats.isEmpty()) {
      return;
    }

    lnElement("h4", "VFS path statistics:");

    lnOpen("table", "class", "phase-statistics");
    lnOpen("tr");
    element("td", "Type");
    element("td", "Frequency");
    element("td", "Duration");
    element("td", "class", "left", "Path");
    close(); // tr

    for (ProfilerTask type : stats) {
      int numPrinted = 0;
      for (Stat stat : stats.getSortedStatistics(type)) {
        lnOpen("tr");
        if (vfsStatsLimit != -1 && numPrinted++ == vfsStatsLimit) {
          open("td", "class", "center", "colspan", "4");
          printf("... %d more ...", stats.getStatisticsCount(type) - vfsStatsLimit);
          close();
          close(); // tr
          break;
        }
        element("td", type.name());
        element("td", stat.getCount());
        element("td", TimeUtilities.prettyTime(stat.getDuration()));
        element("td", "class", "left", stat.path);
        close(); // tr
      }
    }

    lnClose(); // table
  }

  /**
   * Print a table for the phase overview with runtime and runtime percentage per phase and total.
   */
  private void printPhaseSummaryStatistics() {
    lnOpen("div", "class", "phase-statistics");
    lnElement("h3", "Phase Summary Information");
    lnOpen("table", "class", "phase-statistics");
    for (ProfilePhase phase : phaseSummaryStats) {
      lnOpen("tr");
      lnOpen("td", "class", "left");
      printf("Total %s phase time", phase.nick);
      close();
      element("td", TimeUtilities.prettyTime(phaseSummaryStats.getDurationNanos(phase)));
      element("td", phaseSummaryStats.getPrettyPercentage(phase));
      lnClose(); // tr
    }
    lnOpen("tr");
    lnElement("td", "class", "left", "Total run time");
    element("td", TimeUtilities.prettyTime(phaseSummaryStats.getTotalDuration()));
    element("td", "100.00%");
    lnClose(); // tr
    lnClose(); // table
    lnClose(); // div
  }

  private void printTwoColumnStatistic(String name, long duration) {
    lnOpen("tr");
    element("td", "class", "left", "colspan", "3", name);
    element("td", TimeUtilities.prettyTime(duration));
    lnClose(); // tr
  }
}


