// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import chart from "./chart.js";
import dom from "./dom.js";
import url from "./url.js";

var commits = null;

const benchmarks = new Set();
const selectedBenchmarks = new Set();

const legends = new Set();
const selectedLegends = new Set();

const zoom = { left: -1, right: -1 };

function forEachBenchmark(callback) {
  for (const benchmark of benchmarks.values()) {
    callback(benchmark, selectedBenchmarks.has(benchmark));
  }
}

function forEachSelectedBenchmark(callback) {
  forEachBenchmark((benchmark, selected) => {
    if (selected) {
      callback(benchmark);
    }
  });
}

function getCommit(index, zoom) {
  return getCommits(zoom)[index];
}

function getCommitFromContext(context) {
  const elementInfo = context[0];
  var commit;
  if (elementInfo.dataset.type == "line") {
    commit = getCommit(elementInfo.dataIndex, zoom);
  } else {
    console.assert(elementInfo.dataset.type == "scatter");
    commit = getCommit(elementInfo.raw.x, zoom);
  }
  return commit;
}

function getCommitDescriptionFromContext(context) {
  const commit = getCommitFromContext(context);
  const elementInfo = context[0];
  const dataset = chart.get().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}`
  );
}

function getCommits(zoom) {
  const commitsForSelectedBranch = commits.filter((commit) =>
    dom.isCommitSelected(commit),
  );
  if (zoom) {
    return commitsForSelectedBranch.slice(zoom.left, zoom.right);
  }
  return commitsForSelectedBranch;
}

function getTryCommitsByParentHash(loadedTryCommits) {
  const result = {};
  for (var i = 0; i < loadedTryCommits.length; i++) {
    const commit = loadedTryCommits[i];
    const parentHash = commit["parent_hash"];
    if (parentHash in result) {
      result[parentHash].push(commit);
    } else {
      result[parentHash] = [commit];
    }
  }
  return result;
}

function hasLegend(legend) {
  return legends.has(legend);
}

function importCommits(url, tryUrl = null) {
  const promises = [import(url, { with: { type: "json" } })];
  if (tryUrl !== null) {
    promises.push(import(tryUrl, { with: { type: "json" } }));
  }
  return Promise.all(promises).then((values) => {
    const loadedCommits = values[0].default;
    const loadedTryCommits = values.length > 1 ? values[1].default : [];
    const loadedTryCommitsByParentHash =
      getTryCommitsByParentHash(loadedTryCommits);
    // Amend the commits with their unique index.
    var mainIndex = 0;
    var releaseIndex = 0;
    const processedCommits = [];
    for (var i = loadedCommits.length - 1; i >= 0; i--) {
      const commit = loadedCommits[i];
      commit.index = commit.version ? releaseIndex++ : mainIndex++;
      processedCommits.push(commit);

      // Include the try commits for this commit on main.
      const hash = commit["hash"];
      if (hash in loadedTryCommitsByParentHash) {
        console.assert(!commit.version, "Try jobs for release not supported");
        const tryCommitsForCurrentCommit = loadedTryCommitsByParentHash[hash];
        for (var j = 0; j < tryCommitsForCurrentCommit.length; j++) {
          const tryCommitForCurrentCommit = tryCommitsForCurrentCommit[j];
          tryCommitForCurrentCommit.index = mainIndex++;
        }
        processedCommits.push(...tryCommitsForCurrentCommit);
      }
    }
    commits = processedCommits;
    return processedCommits;
  });
}

function initializeBenchmarks() {
  for (const commit of commits.values()) {
    for (const benchmark in commit.benchmarks) {
      benchmarks.add(benchmark);
    }
  }
  for (const benchmark of benchmarks.values()) {
    if (url.matches(benchmark)) {
      selectedBenchmarks.add(benchmark);
    }
  }
  if (selectedBenchmarks.size == 0) {
    const randomBenchmarkIndex = Math.floor(Math.random() * benchmarks.size);
    const randomBenchmark = Array.from(benchmarks)[randomBenchmarkIndex];
    selectedBenchmarks.add(randomBenchmark);
  }
}

function initializeLegends(legendsInfo) {
  for (var legend in legendsInfo) {
    legends.add(legend);
    if (url.contains(legend)) {
      selectedLegends.add(legend);
    }
  }
  if (selectedLegends.size == 0) {
    for (let [legend, legendInfo] of Object.entries(legendsInfo)) {
      if (legendInfo.default) {
        selectedLegends.add(legend);
      }
    }
  }
}

function initializeZoom() {
  const filteredCommits = resetZoom();
  for (const urlOption of url.values()) {
    if (urlOption.startsWith("L")) {
      var left = parseInt(urlOption.substring(1));
      if (isNaN(left)) {
        continue;
      }
      left = left >= 0 ? left : filteredCommits.length + left;
      if (left < 0) {
        zoom.left = 0;
      } else if (left >= filteredCommits.length) {
        zoom.left = filteredCommits.length - 1;
      } else {
        zoom.left = left;
      }
    }
  }
}

function resetZoom() {
  const filteredCommits = getCommits(null);
  zoom.left = Math.max(0, filteredCommits.length - 75);
  zoom.right = filteredCommits.length;
  return filteredCommits;
}

function handleKeyDownEvent(e, callback) {
  if (selectedBenchmarks.size != 1) {
    return;
  }
  const [selectedBenchmark] = selectedBenchmarks;
  var benchmarkToSelect = null;
  var previousBenchmark = null;
  for (const benchmark of benchmarks.values()) {
    if (previousBenchmark != null) {
      if (e.key == "ArrowLeft" && benchmark == selectedBenchmark) {
        benchmarkToSelect = previousBenchmark;
        break;
      } else if (
        e.key === "ArrowRight" &&
        previousBenchmark == selectedBenchmark
      ) {
        benchmarkToSelect = benchmark;
        break;
      }
    }
    previousBenchmark = benchmark;
  }
  if (benchmarkToSelect != null) {
    selectedBenchmarks.clear();
    selectedBenchmarks.add(benchmarkToSelect);
    document.getElementById(selectedBenchmark).checked = false;
    document.getElementById(benchmarkToSelect).checked = true;
    callback();
  }
}

function isLegendSelected(legend) {
  return selectedLegends.has(legend);
}

export default {
  benchmarks: benchmarks,
  commits: getCommits,
  legends: legends,
  selectedBenchmarks: selectedBenchmarks,
  selectedLegends: selectedLegends,
  forEachBenchmark: forEachBenchmark,
  forEachSelectedBenchmark: forEachSelectedBenchmark,
  getCommit: getCommit,
  getCommitFromContext: getCommitFromContext,
  getCommitDescriptionFromContext: getCommitDescriptionFromContext,
  handleKeyDownEvent: handleKeyDownEvent,
  hasLegend: hasLegend,
  initializeBenchmarks: initializeBenchmarks,
  initializeLegends: initializeLegends,
  initializeZoom: initializeZoom,
  importCommits: importCommits,
  isLegendSelected: isLegendSelected,
  resetZoom: resetZoom,
  zoom: zoom,
};
