<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>R8 perf</title>
</head>
<body>
  <div id="benchmark-selectors"></div>
  <div>
      <canvas id="myChart"></canvas>
  </div>
  <div>
    <div style="float: left; width: 50%">
      <button type="button" id="show-more-left" disabled>⇐</button>
      <button type="button" id="show-less-left">⇒</button>
    </div>
    <div style="float: left; text-align: right; width: 50%">
      <button type="button" id="show-less-right">⇐</button>
      <button type="button" id="show-more-right" disabled>⇒</button>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.3/dist/chart.umd.min.js"></script>
  <script type="module">
    // Utility methods.
    Array.prototype.any = function(predicate) {
      for (const element of this.values()) {
        if (predicate(element)) {
          return true;
        }
      }
      return false;
    };
    Array.prototype.first = function() {
      return this[0];
    };
    Array.prototype.avg = function() {
      return this.reduce(function(x, y) { return x + y; }, 0) / this.length;
    };
    Array.prototype.min = function() {
      return this.reduce(function(x, y) { return x === null ? y : Math.min(x, y); }, null);
    };
    Array.prototype.reverseInPlace = function() {
      for (var i = 0; i < Math.floor(this.length / 2); i++) {
        var temp = this[i];
        this[i] = this[this.length - i - 1];
        this[this.length - i - 1] = temp;
      }
    };
    Number.prototype.ns_to_s = function() {
      const seconds = this/10E8;
      const seconds_with_one_decimal = Math.round(seconds*10)/10;
      return seconds;
    };

    // Import and reverse commits so that newest are last.
    import commits from "./benchmark_data.json" with { type: "json" };
    commits.reverseInPlace();

    // Amend the commits with their unique index.
    for (var i = 0; i < commits.length; i++) {
      commits[i].index = i;
    }

    // DOM references.
    const benchmarkSelectors = document.getElementById('benchmark-selectors');
    const canvas = document.getElementById('myChart');
    const showMoreLeft = document.getElementById('show-more-left');
    const showLessLeft = document.getElementById('show-less-left');
    const showLessRight = document.getElementById('show-less-right');
    const showMoreRight = document.getElementById('show-more-right');

    // Initialize benchmark selectors.
    const benchmarks = new Set();
    for (const commit of commits.values()) {
      for (const benchmark in commit.benchmarks) {
          benchmarks.add(benchmark);
      }
    }
    const selectedBenchmarks = new Set();
    const urlOptions = unescape(window.location.hash.substring(1)).split(',');
    for (const benchmark of benchmarks.values()) {
      for (const filter of urlOptions.values()) {
        if (filter) {
          const match = benchmark.match(new RegExp(filter.replace("*", ".*")));
          if (match) {
            selectedBenchmarks.add(benchmark);
            break;
          }
        }
      }
    }
    if (selectedBenchmarks.size == 0) {
      selectedBenchmarks.add(benchmarks.values().next().value);
    }
    for (const benchmark of benchmarks.values()) {
      const input = document.createElement('input');
      input.type = 'checkbox';
      input.name = 'benchmark';
      input.id = benchmark;
      input.value = benchmark;
      input.checked = selectedBenchmarks.has(benchmark);
      input.onchange = function (e) {
        if (e.target.checked) {
          selectedBenchmarks.add(e.target.value);
        } else {
          selectedBenchmarks.delete(e.target.value);
        }
        updateChart(true, false);
      };

      const label = document.createElement('label');
      label.id = benchmark + 'Label';
      label.htmlFor = benchmark;
      label.innerHTML = benchmark;

      benchmarkSelectors.appendChild(input);
      benchmarkSelectors.appendChild(label);
    }

    // Chart data provider.
    function getData() {
      const filteredCommits = commits.slice(zoom.left, zoom.right);
      const labels = filteredCommits.map((c, i) => c.index);
      const datasets = [];
      for (const selectedBenchmark of selectedBenchmarks.values()) {
        const codeSizeData =
            filteredCommits.map(
                (c, i) =>
                    selectedBenchmark in filteredCommits[i].benchmarks
                        ? filteredCommits[i]
                            .benchmarks[selectedBenchmark]
                            .results
                            .first()
                            .code_size
                        : NaN);
        const codeSizeScatterData = [];
        for (const commit of filteredCommits.values()) {
          if (!(selectedBenchmark in commit.benchmarks)) {
            continue;
          }
          const codeSizes =
              commit.benchmarks[selectedBenchmark].results.map(result => result.code_size)
          const expectedCodeSize = codeSizes.first();
          if (codeSizes.any(codeSize => codeSize != expectedCodeSize)) {
            const seen = new Set();
            seen.add(expectedCodeSize);
            for (const codeSize of codeSizes.values()) {
              if (!seen.has(codeSize)) {
                codeSizeScatterData.push({ x: commit.index, y: codeSize });
                seen.add(codeSize);
              }
            }
          }
        }
        const runtimeData =
            filteredCommits.map(
                (c, i) =>
                    selectedBenchmark in filteredCommits[i].benchmarks
                        ? filteredCommits[i]
                            .benchmarks[selectedBenchmark]
                            .results
                            .map(result => result.runtime)
                            .min()
                            .ns_to_s()
                        : NaN);
        const runtimeScatterData = [];
        for (const commit of filteredCommits.values()) {
          if (!(selectedBenchmark in commit.benchmarks)) {
            continue;
          }
          const runtimes =
              commit.benchmarks[selectedBenchmark].results.map(result => result.runtime)
          for (const runtime of runtimes.values()) {
            runtimeScatterData.push({ x: commit.index, y: runtime.ns_to_s() });
          }
        }

        const skipped = (ctx, value) => ctx.p0.skip || ctx.p1.skip ? value : undefined;
        datasets.push(...[
          {
            benchmark: selectedBenchmark,
            type: 'line',
            label: 'Code size',
            data: codeSizeData,
            tension: 0.1,
            segment: {
              borderColor: ctx =>
                  skipped(
                      ctx,
                      myChart
                          ? myChart.data.datasets[ctx.datasetIndex].backgroundColor
                          : undefined),
              borderDash: ctx => skipped(ctx, [6, 6]),
            },
            spanGaps: true
          },
          {
            benchmark: selectedBenchmark,
            type: 'scatter',
            label: 'Nondeterminism',
            data: codeSizeScatterData,
            radius: 6,
            pointBackgroundColor: 'red'
          },
          {
            benchmark: selectedBenchmark,
            type: 'line',
            label: 'Runtime',
            data: runtimeData,
            tension: 0.1,
            yAxisID: 'y2',
            segment: {
              borderColor: ctx =>
                  skipped(ctx, myChart.data.datasets[ctx.datasetIndex].backgroundColor),
              borderDash: ctx => skipped(ctx, [6, 6]),
            },
            spanGaps: true
          },
          {
            benchmark: selectedBenchmark,
            type: 'scatter',
            label: 'Runtime variance',
            data: runtimeScatterData,
            yAxisID: 'y2'
          }
        ]);
      }

      return {
        labels: labels,
        datasets: datasets,
      };
    }

    // Legend tracking.
    const legends =
        new Set(['Code size', 'Nondeterminism', 'Runtime', 'Runtime variance']);
    const selectedLegends =
        new Set(
              unescape(window.location.hash.substring(1))
                  .split(',')
                  .filter(l => legends.has(l)));
    if (selectedLegends.size == 0) {
      legends.forEach(l => selectedLegends.add(l));
    }

    // Chart options.
    const options = {
      onHover: (event, chartElement) =>
          event.native.target.style.cursor =
              chartElement[0] ? 'pointer' : 'default',
      plugins: {
        legend: {
          labels: {
            filter: function(legendItem, data) {
              // Only retain the legends for the first selected benchmark. If
              // multiple benchmarks are selected, then use the legends of the
              // first selected benchmark to control all selected benchmarks.
              const numUniqueLegends =
                  data.datasets.length / selectedBenchmarks.size;
              return legendItem.datasetIndex < numUniqueLegends;
            },
          },
          onClick: function legendClickHandler(e, legendItem, legend) {
            const clickedLegend = legendItem.text;
            if (selectedLegends.has(clickedLegend)) {
              selectedLegends.delete(clickedLegend);
            } else {
              selectedLegends.add(clickedLegend);
            }
            updateChart(false, true);
          },
        },
        tooltip: {
          callbacks: {
            title: (context) => {
              const elementInfo = context[0];
              var commit;
              if (elementInfo.dataset.type == 'line') {
                commit = commits[zoom.left + elementInfo.dataIndex];
              } else {
                console.assert(elementInfo.dataset.type == 'scatter');
                commit = commits[elementInfo.raw.x];
              }
              return commit.title;
            },
            footer: (context) => {
              const elementInfo = context[0];
              var commit;
              if (elementInfo.dataset.type == 'line') {
                commit = commits[zoom.left + elementInfo.dataIndex];
              } else {
                console.assert(elementInfo.dataset.type == 'scatter');
                commit = commits[elementInfo.raw.x];
              }
              const dataset = myChart.data.datasets[elementInfo.datasetIndex];
              return `App: ${dataset.benchmark}\n`
                  + `Author: ${commit.author}\n`
                  + `Submitted: ${new Date(commit.submitted * 1000).toLocaleString()}\n`
                  + `Hash: ${commit.hash}\n`
                  + `Index: ${commit.index}`;
            }
          }
        }
      },
      responsive: true,
      scales: {
        x: {},
        y: {
          position: 'left',
          title: {
            display: true,
            text: 'Code size (bytes)'
          }
        },
        y2: {
          position: 'right',
          title: {
            display: true,
            text: 'Runtime (seconds)'
          }
        }
      }
    };

    // Setup click handler.
    canvas.onclick = function (event) {
      const points =
          myChart.getElementsAtEventForMode(
              event, 'nearest', { intersect: true }, true);
      if (points.length > 0) {
        const point = points[0];
        const commit = commits[point.index];
        window.open('https://r8.googlesource.com/r8/+/' + commit.hash, '_blank');
      }
    };

    // Setup chart navigation.
    var zoom = { left: 0, right: commits.length };
    for (const urlOption of urlOptions.values()) {
      if (urlOption.startsWith('L')) {
        var left = parseInt(urlOption.substring(1));
        if (isNaN(left)) {
          continue;
        }
        left = left >= 0 ? left : commits.length + left;
        if (left < 0) {
          zoom.left = 0;
        } else if (left >= commits.length) {
          zoom.left = commits.length - 1;
        } else {
          zoom.left = left;
        }
      }
    }

    showMoreLeft.onclick = function (event) {
      if (zoom.left == 0) {
        return;
      }
      const currentSize = zoom.right - zoom.left;
      zoom.left = zoom.left - currentSize;
      if (zoom.left < 0) {
        zoom.left = 0;
      }
      updateChart(true, false);
    };

    showLessLeft.onclick = function (event) {
      const currentSize = zoom.right - zoom.left;
      zoom.left = zoom.left + Math.floor(currentSize / 2);
      if (zoom.left >= zoom.right) {
        zoom.left = zoom.right - 1;
      }
      updateChart(true, false);
    };

    showLessRight.onclick = function (event) {
      if (zoom.right == 0) {
        return;
      }
      const currentSize = zoom.right - zoom.left;
      zoom.right = zoom.right - Math.floor(currentSize / 2);
      if (zoom.right < zoom.left) {
        zoom.right = zoom.left;
      }
      updateChart(true, false);
    };

    showMoreRight.onclick = function (event) {
      const currentSize = zoom.right - zoom.left;
      zoom.right = zoom.right + currentSize;
      if (zoom.right > commits.length) {
        zoom.right = commits.length;
      }
      updateChart(true, false);
    };

    function updateChart(dataChanged, legendsChanged) {
      console.assert(zoom.left <= zoom.right);

      // Update datasets.
      if (dataChanged) {
        const newData = getData();
        Object.assign(myChart.data, newData);
        // Update chart.
        myChart.update();
      }

      // Update legends.
      if (legendsChanged || (dataChanged && selectedLegends.size < legends.size)) {
        for (var datasetIndex = 0;
            datasetIndex < myChart.data.datasets.length;
            datasetIndex++) {
          const datasetMeta = myChart.getDatasetMeta(datasetIndex);
          datasetMeta.hidden = !selectedLegends.has(datasetMeta.label);
        }
        // Update chart.
        myChart.update();
      }


      // Update checkbox colors.
      const benchmarkColors = {};
      for (var datasetIndex = 0;
          datasetIndex < myChart.data.datasets.length;
          datasetIndex++) {
        if (myChart.getDatasetMeta(datasetIndex).hidden) {
          continue;
        }
        const dataset = myChart.data.datasets[datasetIndex];
        const benchmark = dataset.benchmark;
        const benchmarkColor = dataset.borderColor;
        if (!(benchmark in benchmarkColors)) {
          benchmarkColors[benchmark] = benchmarkColor;
        }
      }
      for (const benchmark of benchmarks.values()) {
        const benchmarkLabel = document.getElementById(benchmark + 'Label');
        const benchmarkColor = benchmarkColors[benchmark] || '#000000';
        const benchmarkFontWeight = benchmark in benchmarkColors ? 'bold' : 'normal';
        benchmarkLabel.style.color = benchmarkColor;
        benchmarkLabel.style.fontWeight = benchmarkFontWeight;
      }

      // Update navigation.
      showMoreLeft.disabled = zoom.left == 0;
      showLessLeft.disabled = zoom.left == zoom.right - 1;
      showLessRight.disabled = zoom.left == zoom.right - 1;
      showMoreRight.disabled = zoom.right == commits.length;

      // Update hash.
      window.location.hash =
          Array.from(selectedBenchmarks)
              .concat(
                  selectedLegends.size == legends.size
                      ? []
                      : Array.from(selectedLegends))
              .join(',');
    }

    // Create chart.
    const myChart = new Chart(canvas, {
      data: getData(),
      options: options
    });

    // Hide disabled legends.
    if (selectedLegends.size < legends.size) {
      updateChart(false, true);
    } else {
      updateChart(false, false);
    }
  </script>
</body>
</html>