<!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
                          ? myChart.data.datasets[ctx.datasetIndex].backgroundColor
                          : undefined),
              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>