#!/usr/bin/python

# Copyright 2011 Google Inc. All Rights Reserved.

from column_chart import ColumnChart
from results_columns import IterationColumn
from results_columns import IterationsCompleteColumn
from results_columns import MaxColumn
from results_columns import MeanColumn
from results_columns import MinColumn
from results_columns import RatioColumn
from results_columns import StandardDeviationColumn
from results_sorter import ResultSorter
from table import Table


class ResultsReport(object):
  DELTA_COLUMN_NAME = "Change"

  def __init__(self, experiment):
    self.experiment = experiment
    self.benchmark_runs = experiment.benchmark_runs
    self.labels = experiment.labels
    self.benchmarks = experiment.benchmarks
    self.baseline = self.labels[0]

  def _SortByLabel(self, runs):
    labels = {}
    for benchmark_run in runs:
      if benchmark_run.label_name not in labels:
        labels[benchmark_run.label_name] = []
      labels[benchmark_run.label_name].append(benchmark_run)
    return labels

  def GetFullTable(self):
    full_columns = []
    max_iterations = 0
    for benchmark in self.benchmarks:
      if benchmark.iterations > max_iterations:
        max_iterations = benchmark.iterations

    for i in range(1, max_iterations + 1):
      full_columns.append(IterationColumn(str(i), i))

    full_columns.append(IterationsCompleteColumn("Completed"))
    full_columns.append(MinColumn("Min"))
    full_columns.append(MaxColumn("Max"))
    full_columns.append(MeanColumn("Avg"))
    full_columns.append(StandardDeviationColumn("Std Dev"))
    full_columns.append(RatioColumn(self.DELTA_COLUMN_NAME))
    return self._GetTable(self.labels, self.benchmarks, self.benchmark_runs,
                          full_columns)

  def GetSummaryTable(self):
    summary_columns = [MeanColumn("Average"),
                       RatioColumn(self.DELTA_COLUMN_NAME)]
    return self._GetTable(self.labels, self.benchmarks, self.benchmark_runs,
                          summary_columns)

  def _GetTable(self, labels, benchmarks, benchmark_runs, columns):
    table = Table("box-table-a")
    label_headings = [Table.Cell("", hidden=True, colspan=2, header=True)]
    for label in labels:
      colspan = len(columns)
      if label.name == self.baseline.name:
        colspan -= 1
      label_headings.append(Table.Cell(label.name, colspan=colspan,
                                       header=True))

    table.AddRow(label_headings)

    column_headings = [Table.Cell("Autotest Key", header=True),
                       Table.Cell("Iterations", header=True)]
    for label in labels:
      for column in columns:
        if (label.name == self.baseline.name and
            column.name == self.DELTA_COLUMN_NAME):
          continue
        column_headings.append(Table.Cell(column.name, header=True))

    table.AddRow(column_headings)

    sorter = ResultSorter(benchmark_runs)

    for benchmark in benchmarks:
      table.AddRow([Table.Cell(benchmark.name)])
      autotest_keys = sorter.GetAutotestKeys(benchmark.name)
      for autotest_key in autotest_keys:
        row = [Table.Cell(autotest_key),
               Table.Cell(benchmark.iterations)]
        for label in labels:
          for column in columns:
            if (label.name == self.baseline.name and
                column.name == self.DELTA_COLUMN_NAME):
              continue
            results = sorter.GetResults(benchmark.name,
                                        autotest_key, label.name)
            baseline_results = sorter.GetResults(benchmark.name,
                                                 autotest_key,
                                                 self.baseline.name)
            value = column.Compute(results, baseline_results)
            if isinstance(value, float):
              value_string = "%.2f" % value
            else:
              value_string = value

            row.append(Table.Cell(value_string))

        table.AddRow(row)

    return table


class TextResultsReport(ResultsReport):
  TEXT = """
===========================================
Results report for: '%s'
===========================================

-------------------------------------------
Benchmark Run Status
-------------------------------------------
%s

Number re-images: %s

-------------------------------------------
Summary
-------------------------------------------
%s

-------------------------------------------
Full Table
-------------------------------------------
%s

-------------------------------------------
Experiment File
-------------------------------------------
%s
===========================================
"""

  def __init__(self, experiment):
    super(TextResultsReport, self).__init__(experiment)

  def GetStatusTable(self):
    status_table = Table("status")
    for benchmark_run in self.benchmark_runs:
      status_table.AddRow([Table.Cell(benchmark_run.name),
                           Table.Cell(benchmark_run.status),
                           Table.Cell(benchmark_run.failure_reason)])
    return status_table

  def GetReport(self):
    return self.TEXT % (self.experiment.name,
                        self.GetStatusTable().ToText(),
                        self.experiment.machine_manager.num_reimages,
                        self.GetSummaryTable().ToText(30),
                        self.GetFullTable().ToText(30),
                        self.experiment.experiment_file)


class HTMLResultsReport(ResultsReport):
  HTML = """
<html>
  <head>
    <style type="text/css">

body {
  font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif;
  font-size: 12px;
}

pre {
  margin: 10px;
  color: #039;
  font-size: 14px;
}

.chart {
  display: inline;
}

.hidden {
  visibility: hidden;
}

.results-section {
  border: 1px solid #b9c9fe;
  margin: 10px;
}

.results-section-title {
  background-color: #b9c9fe;
  color: #039;
  padding: 7px;
  font-size: 14px;
  width: 200px;
}

.results-section-content {
  margin: 10px;
  padding: 10px;
  overflow:auto;
}

#box-table-a {
  font-size: 12px;
  width: 480px;
  text-align: left;
  border-collapse: collapse;
}

#box-table-a th {
  padding: 6px;
  background: #b9c9fe;
  border-right: 1px solid #fff;
  border-bottom: 1px solid #fff;
  color: #039;
  text-align: center;
}

#box-table-a td {
  padding: 4px;
  background: #e8edff;
  border-bottom: 1px solid #fff;
  border-right: 1px solid #fff;
  color: #669;
  border-top: 1px solid transparent;
}

#box-table-a tr:hover td {
  background: #d0dafd;
  color: #339;
}

    </style>
    <script type='text/javascript' src='https://www.google.com/jsapi'></script>
    <script type='text/javascript'>
      google.load('visualization', '1', {packages:['corechart']});
      google.setOnLoadCallback(init);
      function init() {
        switchTab('summary', 'html');
        switchTab('full', 'html');
        drawTable();
      }
      function drawTable() {
        %s
      }
      function switchTab(table, tab) {
        document.getElementById(table + '-html').style.display = 'none';
        document.getElementById(table + '-text').style.display = 'none';
        document.getElementById(table + '-tsv').style.display = 'none';
        document.getElementById(table + '-' + tab).style.display = 'block';
      }
    </script>
  </head>

  <body>
    <div class='results-section'>
      <div class='results-section-title'>Summary Table</div>
      <div class='results-section-content'>
        <div id='summary-html'>%s</div>
        <div id='summary-text'><pre>%s</pre></div>
        <div id='summary-tsv'><pre>%s</pre></div>
      </div>
      %s
    </div>
    <div class='results-section'>
      <div class='results-section-title'>Charts</div>
      <div class='results-section-content'>%s</div>
    </div>
    <div class='results-section'>
      <div class='results-section-title'>Full Table</div>
      <div class='results-section-content'>
        <div id='full-html'>%s</div>
        <div id='full-text'><pre>%s</pre></div>
        <div id='full-tsv'><pre>%s</pre></div>
      </div>
      %s
    </div>
    <div class='results-section'>
      <div class='results-section-title'>Experiment File</div>
      <div class='results-section-content'>
        <pre>%s</pre>
    </div>
    </div>
  </body>
</html>
"""

  def __init__(self, experiment):
    super(HTMLResultsReport, self).__init__(experiment)

  def _GetTabMenuHTML(self, table):
    return """
<div class='tab-menu'>
  <a href="javascript:switchTab('%s', 'html')">HTML</a>
  <a href="javascript:switchTab('%s', 'text')">Text</a>
  <a href="javascript:switchTab('%s', 'tsv')">TSV</a>
</div>""" % (table, table, table)

  def GetReport(self):
    chart_javascript = ""
    charts = self._GetCharts(self.labels, self.benchmarks, self.benchmark_runs)
    for chart in charts:
      chart_javascript += chart.GetJavascript()
    chart_divs = ""
    for chart in charts:
      chart_divs += chart.GetDiv()

    summary_table = self.GetSummaryTable()
    full_table = self.GetFullTable()
    return self.HTML % (chart_javascript,
                        summary_table.ToHTML(),
                        summary_table.ToText(),
                        summary_table.ToTSV(),
                        self._GetTabMenuHTML("summary"),
                        chart_divs,
                        full_table.ToHTML(),
                        full_table.ToText(),
                        full_table.ToTSV(),
                        self._GetTabMenuHTML("full"),
                        self.experiment.experiment_file)

  def _GetCharts(self, labels, benchmarks, benchmark_runs):
    charts = []
    sorter = ResultSorter(benchmark_runs)

    for benchmark in benchmarks:
      autotest_keys = sorter.GetAutotestKeys(benchmark.name)

      for autotest_key in autotest_keys:
        title = "%s: %s" % (benchmark.name, autotest_key.replace("/", " "))
        chart = ColumnChart(title, 300, 200)
        chart.AddColumn("Label", "string")
        chart.AddColumn("Average", "number")
        chart.AddColumn("Min", "number")
        chart.AddColumn("Max", "number")
        chart.AddSeries("Min", "line", "black")
        chart.AddSeries("Max", "line", "black")

        for label in labels:
          res = sorter.GetResults(benchmark.name, autotest_key, label.name)
          avg_val = MeanColumn("").Compute(res, None)
          min_val = MinColumn("").Compute(res, None)
          max_val = MaxColumn("").Compute(res, None)
          chart.AddRow([label.name, avg_val, min_val, max_val])
          if isinstance(avg_val, str):
            chart = None
            break

        if chart:
          charts.append(chart)
    return charts

