// Copyright 2025 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


// Controller for the Dawn failure expectations browser.


const width = 700;
const height = 700;

// The application state.
// The UI sets configuration parameters and callbacks.
// The application logic populates values from the file.
var Model = {
  file: undefined,
  file_lines: undefined,

  // Derived from file data
  num_leaves: 1, // updated on reread
  counted_data: undefined, // treemap data for failure counts by path
  counted_tags: undefined, // treemap data for tag counts
  live_tags: new Set(), // The set of leaf tags that are currently valid
  treemap_id_to_node: undefined,
  treemap_svg_node: undefined,

  // Dependent on file data.
  focus_tags: [], // only show items with these tags. Acts a stack
  path_prefix: '', // path prefix for all shown items

  // Derived from UI controls
  path_substring: '',
  max_levels: 4, // Level of detail
  show_skip: true,
  show_fail: true,
  show_retry: true,
  show_slow: true,
  show_with_bug: true,
  show_without_bug: true,

  show_cat_accuracy: true,
  show_cat_critical: true,
  show_cat_spurious: true,
  show_cat_none: true,

  // Callbacks that control the UI.

  // The function that will display numbered text lines.
  // e.g. numbered_lines_displayer([{lineNumber:1,line:"foo"}, {lineNumber:16,line:"bar"}])
  numbered_lines_displayer: (list_of_number_and_text) => {},

  detail_incrementer: () => {},
  node_name_displayer: (str,index) => {},
  tag_name_displayer: (str,index) => {},
};

function resetFileDerivedData() {

  Model.num_leaves = 1;
  Model.counted_data = undefined;
  Model.counted_tags = undefined;
  Model.live_tags = new Set();
  Model.treemap_id_to_node = undefined;
  Model.treemap_svg_node = undefined;

  Model.focus_tags = [];
  Model.path_prefix = '';

  // Clear outputs and controls
  Model.node_name_displayer('',0); // clear the path control
  Model.node_name_displayer('',1);
  Model.node_name_displayer('',2);
  Model.tag_name_displayer('',0);
  Model.tag_name_displayer('',1);
  Model.tag_name_displayer('',2);
  Model.numbered_lines_displayer([]);
}
resetFileDerivedData();


// Unique IDs, for elements and clip paths.
var count = 0;

function uid(name) {
  return new Id("O-" + (name == null ? "" : name + "-") + ++count);
}

function Id(id) {
  this.id = id;
  this.href = new URL(`#${id}`, location) + "";
}

Id.prototype.toString = function() {
  return "url(" + this.href + ")";
};


// Treemap generation, for visualizing hierarchical test counts.
function makeTreemap(counted_hierarchy) {
  const sorted = counted_hierarchy.sort((a, b) => b.height - a.height || b.value - a.value);
  const data = sorted;
  Model.num_leaves = data.value;

  // Specify the color scale.
  // Protect against the case where there is no data at all.
  const color = d3.scaleOrdinal((data.children ?? []).map(d => d.data.id), d3.schemeTableau10);

  // Compute the layout.
  const root = d3.treemap()
    .tile(d3.treemapSquarify) // e.g., d3.treemapSquarify
    .size([width, height])
    .padding(0)
    .round(true)
  (data);

  // Create the SVG container.
  const svg = d3.create("svg")
      .attr("viewBox", [0, 0, width, height])
      .attr("width", width)
      .attr("height", height)
      .attr("style", `min-width: 30%;
                      max-width: 100%;
                      height: auto;
                      font: 15px sans-serif;
                      border: 1px solid black`);

  // Add a cell for each node of the hierarchy.
  const cell = svg.selectAll("g")
    .data(root.descendants())
    .join("g");

  const format5 = d3.format("5,d");
  const format = d3.format(",d");
  const percent_format = d3.format(".2%");
  function showNodeText(d) {
    if (Model.node_name_displayer) {
      Model.node_name_displayer(d.data.id??'',1);
      Model.node_name_displayer(`${format5(d.value)} / ${Model.num_leaves} = ${percent_format(d.value / Model.num_leaves)}`,2);
    }
  }

  cell.on("click", (e,target) => {
    if (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey) {
      handleSetPathPrefixOut();
    } else {
      handleSetPathPrefix(target.data.id);
    }
  });
  cell.on("mouseover", (e,target) => showNodeText(target));

  // Append a tooltip.
  cell.append("title")
      //.text(d => `${d.ancestors().reverse().map(d => d.data.id).join(".")}\n${format(d.value)}`);
      .text(d => {Model.node_name_displayer(d.id,1); `${d.data.name}\n${format(d.value)}`;});

  cell.append("path")
      .attr("id", d => (d.cellUid = uid("cell")))
      .attr("fill", d => color(d.data.id))
      .attr("fill-opacity", 0.9)
      .attr("stroke", 'white')
      .attr("d", d => (`M ${d.x0} ${d.y0} L ${d.x1} ${d.y0} L ${d.x1} ${d.y1} L ${d.x0} ${d.y1} Z`));

  // Append a clipPath to ensure text does not overflow.
  cell.append("clipPath")
      .attr("id", d => (d.clipUid = uid("clip")))
    .append("use")
      .attr("xlink:href", d => d.cellUid.href);

  Model.treemap_svg_node = svg.node();
  setTreemapDetailLevel();

  container.replaceChildren(svg.node());
}

// Circular packmap generation, for visualizing tags.
function makePackmap(data) {

  const pack = d3.pack()
    .size([width, height])
    .padding(1);

  const root = pack(data);

  const svg = d3.create("svg")
      .attr("viewBox", [0, 0, width, height])
      .attr("width", width)
      .attr("height", height)
      .attr("style", `min-width: 25%;
                      max-width: 100%;
                      height: auto;
                      font: 15px sans-serif;
                      border: 1px solid black`)
      .attr("text-anchor", "middle");

  const node = svg.append("g")
      .selectAll()
      .data(root.descendants())
      .join("g")
        .attr("transform", d => `translate(${d.x},${d.y})`);

  node.append("circle")
      .attr("r", d => d.r ??  1)
      .attr("fill", d => d.children ? "white" : "#ccc")
      .attr("stroke", d => d.children ? "black" : null);

  const text = node
      .filter(d => !d.children && d.r > 20)
      .append("text")
          .attr("clip-path", d => `circle(${d.r})`);

  text.selectAll()
      .data(d => [d.data.id])
      .join("tspan")
          .text(d=>d);

  function showTagText(d) {
    Model.tag_name_displayer(d.data.id??'',1);
    Model.tag_name_displayer(`${d.value}`,2);
  }

  node.on("click", (e,target) => {
    if (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey) {
      handleSetFocusTagOut();
    } else {
      handleSetFocusTag(target.data.id);
    }
  });
  node.on("mouseover", (e,target) => showTagText(target));

  tag_container.replaceChildren(svg.node());
}

function shouldBeVisible(d) {
  if (d.depth == Model.max_levels) { return true; }
  return d.depth < Model.max_levels && (!('children' in d));
}

function setTreemapDetailLevel() {
  if (Model.treemap_svg_node) {
    d3.select(Model.treemap_svg_node)
      .selectAll("g")
      .attr("visibility", (d) => (shouldBeVisible(d) ? "visible" : "hidden"));
  }
}

// File reading
function readFileToArrayBrowser(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();

    reader.onload = function(event) {
      const text = event.target.result;
      const lines = text.split('\n');
      resolve(lines);
    };

    reader.onerror = function(error) {
      reject(error);
    };

    reader.readAsText(file);
  });
}

async function readfile(file) {
  try {
    const lines = await readFileToArrayBrowser(file);
    return lines;
  } catch (error) {
    console.error('Error reading file:', error);
  }
  return [];
}

async function updateFromFile() {
  if (Model.file !== undefined) {
    Model.file_lines = await readfile(Model.file);

    resetFileDerivedData();
    updateFromLines();
  }
}

async function updateFromLines() {
  if (Model.file_lines === undefined) {
    return;
  }
  const rowPredicate = (row) => {
    if (row.pathString.indexOf(Model.path_substring) < 0) { return false; }
    if (!row.pathString.startsWith(Model.path_prefix)) { return false; }
    if (!Model.show_skip && row.verdict === 'Skip') { return false; }
    if (!Model.show_fail && row.verdict === 'Failure') { return false; }
    if (!Model.show_retry && row.verdict === 'RetryOnFailure') { return false; }
    if (!Model.show_slow && row.verdict === 'Slow') { return false; }
    const has_bug = ! row.bug.match(/\/0+$/);
    if (!Model.show_with_bug && has_bug) { return false; }
    if (!Model.show_without_bug && !has_bug) { return false; }
    // Reject if there is a focus tag that is not in the row.
    if (Model.focus_tags.filter(t => row.tags.indexOf(t) < 0).length > 0) { return false; }

    // Triage categories
    if (!Model.show_cat_none && row.categories.size == 0) { return false; }
    if (!Model.show_cat_accuracy && row.categories.has('Accuracy')) { return false; }
    if (!Model.show_cat_critical && row.categories.has('Critical')) { return false; }
    if (!Model.show_cat_spurious && row.categories.has('Spurious')) { return false; }
    return true;
  };
  const rows = prestratifyExpectationLines(Model.file_lines, rowPredicate);
  const stratified = d3.stratify()
    .id((d) => d.id)
    .parentId((d) => d.parentId)
    (rows);

  Model.counted_data = d3.hierarchy(stratified).count();

  Model.treemap_id_to_node = {};
  Model.counted_data.descendants().forEach((d) => {Model.treemap_id_to_node[d.data.id] = d;});

  // Count occurrences of tags in filtered data.
  const tag_count = {};
  for (d of Model.counted_data.leaves()) {
    for (tag of (d.data.data.tags ?? [])) {
      tag_count[tag] = 1 + (tag_count[tag]??0);
    }
  }
  // Create parent-child rows for tag-group relations.
  const group_rows = [];
  // Link each tag to its tag group.
  const tag_group_dict = parseTagGroups(Model.file_lines);
  const live_groups = new Set();
  Model.live_tags = new Set();
  for (const [group, tags] of Object.entries(tag_group_dict)) {
    for (const tag of tags) {
      const entry = {id: tag, parentId: group, count: (tag_count[tag] ?? 0)};
      if (entry.count > 0) {
        group_rows.push(entry);
        live_groups.add(group);
        Model.live_tags.add(tag);
      }
    }
  }
  // Ensure there is a synthetic root.
  const kSyntheticTagRoot = 'All tags';
  group_rows.push({ id: kSyntheticTagRoot, count: 0 });
  // Link each tag groups to the synthetic root.
  for (const group of live_groups.values()) {
    group_rows.push({ id: group, parentId: kSyntheticTagRoot, count: 0 });
  }

  const stratified_tags = d3.stratify()
    .id(d => d.id)
    .parentId(d => d.parentId)
    (group_rows);

  const root = d3.hierarchy(stratified_tags);
  Model.counted_tags = root.sum(d => d.data.count).sort((a,b) => b.value - a.value);

  updateGraphs();

  // Display the rows, but only if they came from original text.
  // That is, don't display the synthetically created interior nodes.
  Model.numbered_lines_displayer(rows.filter((row) => row.hasOwnProperty('lineNumber')));
}

async function updateGraphs() {
  if (Model.counted_data !== undefined) {
    makeTreemap(Model.counted_data);
  }
  if (Model.counted_tags !== undefined) {
    makePackmap(Model.counted_tags);
  }
}


// Controller

async function handleInputFile(f) {
  Model.file = f;
  updateFromFile();
}

async function handleSetLevel(value) {
  Model.max_levels = value;
  setTreemapDetailLevel();
}

async function handleSetPathPrefix(path) {
  if (path === Model.path_prefix) {
    // The user clicked on the treemap node, but it's already
    // the whole treemap.  Increment level of detail if the
    // node has children.
    const node = (Model.treemap_id_to_node ?? {})[path] ?? {};
    if ((node.children ?? []).length > 0) {
      Model.detail_incrementer();
    }
  } else {
    Model.path_prefix = path;
    Model.node_name_displayer(Model.path_prefix, 0);
    updateFromLines();
  }
}

async function handleSetPathPrefixOut() {
  Model.path_prefix = parentOf(Model.path_prefix); // parentOf is in the other module.
  Model.node_name_displayer(Model.path_prefix, 0);
  updateFromLines();
}

async function handleSetPathSubstring(path) {
  if (path !== Model.path_substring) {
    console.log(`setting path substring ${path}`);
    Model.path_substring = path;
    updateFromLines();
  }
}

async function handleSetFocusTag(tag) {
  if (Model.live_tags.has(tag) && Model.focus_tags.indexOf(tag) < 0) {
    Model.focus_tags.push(tag);
    Model.tag_name_displayer(Model.focus_tags.join(' '), 0);
    updateFromLines();
  }
}

async function handleSetFocusTagOut() {
  if (Model.focus_tags.length > 0) {
    Model.focus_tags.pop();
    Model.tag_name_displayer(Model.focus_tags.join(' '), 0);
    updateFromLines();
  }
}

async function handleSetShow(name, checked) {
  Model[`show_${name}`] = checked;
  updateFromLines();
}

function SetNodeNameDisplayer(fn) {
  Model.node_name_displayer = fn;
}

function SetTagNameDisplayer(fn) {
  Model.tag_name_displayer = fn;
}

function SetNumberedLinesDisplayer(fn) {
  Model.numbered_lines_displayer = fn;
}

function SetDetailIncrementer(fn) {
  Model.detail_incrementer = fn;
}
