<!DOCTYPE html>
<!--
Copyright (c) 2015 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<link rel="import" href="/tracing/base/units/histogram.html">
<link rel="import" href="/tracing/base/units/scalar.html">
<link rel="import" href="/tracing/base/units/units.html">
<link rel="import" href="/tracing/extras/rail/rail_interaction_record.html">
<link rel="import" href="/tracing/ui/base/dom_helpers.html">
<link rel="import" href="/tracing/ui/base/info_bar_group.html">
<link rel="import" href="/tracing/ui/base/overlay.html">
<link rel="import" href="/tracing/ui/base/table.html">
<link rel="import" href="/tracing/ui/units/generic_table_view.html">
<link rel="import" href="/tracing/ui/units/histogram_span.html">
<link rel="import" href="/tracing/ui/units/scalar_span.html">
<link rel="import" href="/perf_insights/results/results.html">
<link rel="import" href="/perf_insights/ui/caching_column.html">
<link rel="import" href="/perf_insights/ui/generic_results_view.html">
<link rel="import" href="/perf_insights/ui/grouping_table.html">
<link rel="import" href="/perf_insights/ui/reports/pi_report.html">
<link rel="import" href="/perf_insights/ui/trace_link_list.html">
<link rel="import" href="/perf_insights/mappers/slice_cost.html">

<polymer-element name="pi-ui-r-rail-score-report"
    extends="pi-ui-r-pi-report"
    map-function-href="/perf_insights/mappers/weather_report_map_function.html"
    map-function-name="weatherReportMapFunction">
  <template>
    <style>
      :host {
        display: flex;
        flex-direction: column;
      }
      #histogram {
        flex: 1 1 auto;
        max-width: 400px;
      }
      #links {
        min-height: 200px;
      }
      h2 {
        font-size: 12pt;
      }
    </style>
    <tr-ui-b-table id="table"></tr-ui-b-table>

    <h2>Score Histogram</h2>
    <tr-ui-u-histogram-span id="histogram"></tr-ui-u-histogram-span>

    <h2>Matching Traces</h2>
    <pi-ui-trace-link-list id="links"></pi-ui-trace-link-list>
  </template>
  <script>
  'use strict';

  Polymer({
    created: function() {
      this.mapResults_ = undefined;
    },

    ready: function() {
      this.$.table.addEventListener('selection-changed', function(tableEvent) {
        tableEvent.stopPropagation();
        this.setHistogramBasedOnSelection_();
      }.bind(this));
      var histogram = this.$.histogram;
      histogram.addEventListener('brushed-bins-changed',
          this.onBrushedBinsChanged_.bind(this));
    },

    onBrushedBinsChanged_: function(event) {
      event.stopPropagation();
      this.setTraceURLsFromBins_(this.$.histogram.brushedBins);
    },

    get mapResults() {
      return this.mapResults_;
    },

    set mapResults(mapResults) {
      this.mapResults_ = mapResults;
      this.updateContents_();
    },

    updateContents_: function() {
      var results = this.mapResults_;
      if (!results)
        results = new tr.r.Results();

      var table = this.$.table;

      var columns = this.createColumns_();
      table.tableColumns = columns;
      table.sortColumnIndex = 0;
      table.sortDescending = false;
      table.selectionMode = tr.ui.b.TableFormat.SelectionMode.ROW;

      var railScoreHistograms = {};
      results.allValuesFromFailureFreeRuns.map(function(v) {
        if (!v.value.irTree)
          return;
        this.addToHistograms_(railScoreHistograms, v.value.irTree, v.runInfo);
      }.bind(this));

      if (!railScoreHistograms.histogram)
        return;

      var overallRow = this.convertToRowAndSubRows_(railScoreHistograms);
      // Mark all first level subrows as using rail sorting.
      if (overallRow.subRows) {
        overallRow.subRows.forEach(function(row) {
          row.isRailName = true;
        });
      }

      overallRow.title = 'Overall RAIL score';
      table.tableRows = [overallRow];
      table.selectedTableRow = overallRow;
      this.setHistogramBasedOnSelection_();
    },

    createColumns_: function() {
      var columns = [{
          title: 'Title',
          value: function(row) {
            return row.title;
          },
          cmp: function(a, b) {
            if (a.isRailName && b.isRailName)
              return tr.e.rail.railCompare(a.title, b.title);
            return a.title.localeCompare(b.title);
          },
          width: '500px'
        },
        {
          title: 'Avg. RAIL score',
          textAlign: 'right',
          value: function(row) {
            return tr.ui.units.createScalarSpan(
                new tr.b.u.Scalar(row.histogram.average,
                                  tr.b.u.Units.normalizedPercentage));
          },
          cmp: function(a, b) {
            return a.histogram.average - b.histogram.average;
          }
        }
      ];
      return columns;
    },

    addToHistograms_: function(histograms, irTree, sourceInfo) {
      histograms.histogram = histograms.histogram ||
          tr.b.u.Histogram.createLinear(
              tr.b.u.Units.normalizedPercentage,
              tr.b.Range.fromExplicitRange(0, 1),
              33);
      if (irTree.overallScore !== undefined)
        histograms.histogram.add(irTree.overallScore, sourceInfo);
      if (irTree.irScores) {
        irTree.irScores.forEach(function(irScore) {
          histograms.histogram.add(irScore, sourceInfo);
        });
      }
      if (!irTree.subTypes)
        return;
      histograms.subTypes = histograms.subTypes || {};
      for (var subType in irTree.subTypes) {
        histograms.subTypes[subType] = histograms.subTypes[subType] || {};
        this.addToHistograms_(histograms.subTypes[subType],
            irTree.subTypes[subType], sourceInfo);
      }
    },

    convertToRowAndSubRows_: function(histograms) {
      var row = {
        histogram: histograms.histogram
      };
      if (!histograms.subTypes)
        return row;
      row.isExpanded = true;
      row.subRows = [];
      for (var subType in histograms.subTypes) {
        var subRow = this.convertToRowAndSubRows_(histograms.subTypes[subType]);
        subRow.title = subType;
        row.subRows.push(subRow);
      }
      return row;
    },

    setTraceURLsFromBins_: function(bins) {
      var urlSet = [];
      bins.forEach(function(bin) {
        bin.sourceInfos.forEach(function(sourceInfo) {
          urlSet[sourceInfo.url] = 1;
        });
      });
      urlSet = Object.keys(urlSet);
      urlSet.sort();
      this.$.links.setTraceUrls(urlSet);
    },

    setHistogramBasedOnSelection_: function() {
      this.$.histogram.histogram = this.$.table.selectedTableRow.histogram;
      this.setTraceURLsFromBins_(this.$.histogram.histogram.allBins);
    }
  });
  </script>
</polymer-element>
