// stackViewer displays a flame-graph like view (extended to show callers).
//   stacks - report.StackSet
//   nodes  - List of names for each source in report.StackSet
function stackViewer(stacks, nodes) {
  'use strict';

  // Constants used in rendering.
  const ROW = 20;
  const PADDING = 2;
  const MIN_WIDTH = 4;
  const MIN_TEXT_WIDTH = 16;
  const TEXT_MARGIN = 2;
  const FONT_SIZE = 12;
  const MIN_FONT_SIZE = 8;

  // Mapping from unit to a list of display scales/labels.
  // List should be ordered by increasing unit size.
  const UNITS = new Map([
    ['B', [
      ['B', 1],
      ['kB', Math.pow(2, 10)],
      ['MB', Math.pow(2, 20)],
      ['GB', Math.pow(2, 30)],
      ['TB', Math.pow(2, 40)],
      ['PB', Math.pow(2, 50)]]],
    ['s', [
      ['ns', 1e-9],
      ['µs', 1e-6],
      ['ms', 1e-3],
      ['s', 1],
      ['hrs', 60*60]]]]);

  // Fields
  let shownTotal = 0;       // Total value of all stacks
  let pivots = [];          // Indices of currently selected data.Sources entries.
  let matches = new Set();  // Indices of sources that match search
  let elems = new Map();    // Mapping from source index to display elements
  let displayList = [];     // List of boxes to display.
  let actionMenuOn = false; // Is action menu visible?
  let actionTarget = null;  // Box on which action menu is operating.

  // Setup to allow measuring text width.
  const textSizer = document.createElement('canvas');
  textSizer.id = 'textsizer';
  const textContext = textSizer.getContext('2d');

  // Get DOM elements.
  const chart = find('stack-chart');
  const search = find('search');
  const actions = find('action-menu');
  const actionTitle = find('action-title');
  const detailBox = find('current-details');

  window.addEventListener('resize', render);
  window.addEventListener('popstate', render);
  search.addEventListener('keydown', handleSearchKey);

  // Withdraw action menu when clicking outside, or when item selected.
  document.addEventListener('mousedown', (e) => {
    if (!actions.contains(e.target)) {
      hideActionMenu();
    }
  });
  actions.addEventListener('click', hideActionMenu);

  // Initialize menus and other general UI elements.
  viewer(new URL(window.location.href), nodes, {
    hiliter: (n, on) => { return hilite(n, on); },
    current: () => {
      let r = new Map();
      for (let p of pivots) {
        r.set(p, true);
      }
      return r;
    }});

  render();

  // Helper functions follow:

  // hilite changes the highlighting of elements corresponding to specified src.
  function hilite(src, on) {
    if (on) {
      matches.add(src);
    } else {
      matches.delete(src);
    }
    toggleClass(src, 'hilite', on);
    return true;
  }

  // Display action menu (triggered by right-click on a frame)
  function showActionMenu(e, box) {
    if (box.src == 0) return; // No action menu for root
    e.preventDefault(); // Disable browser context menu
    const src = stacks.Sources[box.src];
    actionTitle.innerText = src.Display[src.Display.length-1];
    const menu = actions;
    menu.style.display = 'block';
    // Compute position so menu stays visible and near the mouse.
    const x = Math.min(e.clientX - 10, document.body.clientWidth - menu.clientWidth);
    const y = Math.min(e.clientY - 10, document.body.clientHeight - menu.clientHeight);
    menu.style.left = x + 'px';
    menu.style.top = y + 'px';
    // Set menu links to operate on clicked box.
    setHrefParam('action-source', 'f', box.src);
    setHrefParam('action-source-tab', 'f', box.src);
    setHrefParam('action-focus', 'f', box.src);
    setHrefParam('action-ignore', 'i', box.src);
    setHrefParam('action-hide', 'h', box.src);
    setHrefParam('action-showfrom', 'sf', box.src);
    toggleClass(box.src, 'hilite2', true);
    actionTarget = box;
    actionMenuOn = true;
  }

  function hideActionMenu() {
    actions.style.display = 'none';
    actionMenuOn = false;
    if (actionTarget != null) {
      toggleClass(actionTarget.src, 'hilite2', false);
    }
  }

  // setHrefParam updates the specified parameter in the  href of an <a>
  // element to make it operate on the specified src.
  function setHrefParam(id, param, src) {
    const elem = document.getElementById(id);
    if (!elem) return;

    let url = new URL(elem.href);
    url.hash = '';

    // Copy params from this page's URL.
    const params = url.searchParams;
    for (const p of new URLSearchParams(window.location.search)) {
      params.set(p[0], p[1]);
    }

    // Update params to include src.
    let v = stacks.Sources[src].RE;
    if (param != 'f' && param != 'sf') { // old f,sf values are overwritten
      // Add new source to current parameter value.
      const old = params.get(param);
      if (old && old != '') {
        v += '|' + old;
      }
    }
    params.set(param, v);

    elem.href = url.toString();
  }

  // Capture Enter key in the search box to make it pivot instead of focus.
  function handleSearchKey(e) {
    if (e.key != 'Enter') return;
    e.stopImmediatePropagation();  // Disable normal enter key handling
    const val = search.value;
    try {
      new RegExp(search.value);
    } catch (error) {
      return;  // TODO: Display error state in search box
    }
    switchPivots(val);
  }

  function switchPivots(regexp) {
    // Switch URL without hitting the server.
    const url = new URL(document.URL);
    url.searchParams.set('p', regexp);
    history.pushState('', '', url.toString()); // Makes back-button work
    matches = new Set();
    search.value = '';
    render();
  }

  function handleEnter(box, div) {
    if (actionMenuOn) return;
    const d = details(box);
    div.title = d + ' ' + stacks.Sources[box.src].FullName;
    detailBox.innerText = d;
    // Highlight all boxes that have the same source as box.
    toggleClass(box.src, 'hilite2', true);
  }

  function handleLeave(box) {
    if (actionMenuOn) return;
    detailBox.innerText = '';
    toggleClass(box.src, 'hilite2', false);
  }

  // Return list of sources that match the regexp given by the 'p' URL parameter.
  function urlPivots() {
    const pivots = [];
    const params = (new URL(document.URL)).searchParams;
    const val = params.get('p');
    if (val !== null && val != '') {
      try {
        const re = new RegExp(val);
        for (let i = 0; i < stacks.Sources.length; i++) {
          const src = stacks.Sources[i];
          if (re.test(src.UniqueName) || re.test(src.FileName)) {
            pivots.push(i);
          }
        }
      } catch (error) {}
    }
    if (pivots.length == 0) {
      pivots.push(0);
    }
    return pivots;
  }

  // render re-generates the stack display.
  function render() {
    pivots = urlPivots();

    // Get places where pivots occur.
    let places = [];
    for (let pivot of pivots) {
      const src = stacks.Sources[pivot];
      for (let p of src.Places) {
        places.push(p);
      }
    }

    const width = chart.clientWidth;
    elems.clear();
    actionTarget = null;
    const total = totalValue(places);
    const xscale = (width-2*PADDING) / total; // Converts from profile value to X pixels
    const x = PADDING;
    const y = 0;
    shownTotal = total;

    displayList.length = 0;
    renderStacks(0, xscale, x, y, places, +1);  // Callees
    renderStacks(0, xscale, x, y-ROW, places, -1);  // Callers (ROW left for separator)
    display(displayList);
  }

  // renderStacks creates boxes with top-left at x,y with children drawn as
  // nested stacks (below or above based on the sign of direction).
  // Returns the largest y coordinate filled.
  function renderStacks(depth, xscale, x, y, places, direction) {
    // Example: suppose we are drawing the following stacks:
    //   a->b->c
    //   a->b->d
    //   a->e->f
    // After rendering a, we will call renderStacks, with places pointing to
    // the preceding stacks.
    //
    // We first group all places with the same leading entry. In this example
    // we get [b->c, b->d] and [e->f]. We render the two groups side-by-side.
    const groups = partitionPlaces(places);
    for (const g of groups) {
      renderGroup(depth, xscale, x, y, g, direction);
      x += xscale*g.sum;
    }
  }

  function renderGroup(depth, xscale, x, y, g, direction) {
    // Skip if not wide enough.
    const width = xscale * g.sum;
    if (width < MIN_WIDTH) return;

    // Draw the box for g.src (except for selected element in upwards direction
    // since that duplicates the box we added in downwards direction).
    if (depth != 0 || direction > 0) {
      const box = {
        x:         x,
        y:         y,
        src:       g.src,
        sum:       g.sum,
        selfValue: g.self,
        width:     xscale*g.sum,
        selfWidth: (direction > 0) ? xscale*g.self : 0,
      };
      displayList.push(box);
      x += box.selfWidth;
    }
    y += direction * ROW;

    // Find child or parent stacks.
    const next = [];
    for (const place of g.places) {
      const stack = stacks.Stacks[place.Stack];
      const nextSlot = place.Pos + direction;
      if (nextSlot >= 0 && nextSlot < stack.Sources.length) {
        next.push({Stack: place.Stack, Pos: nextSlot});
      }
    }
    renderStacks(depth+1, xscale, x, y, next, direction);
  }

  // partitionPlaces partitions a set of places into groups where each group
  // contains places with the same source. If a stack occurs multiple times
  // in places, only the outer-most occurrence is kept.
  function partitionPlaces(places) {
    // Find outer-most slot per stack (used later to elide duplicate stacks).
    const stackMap = new Map();  // Map from stack index to outer-most slot#
    for (const place of places) {
      const prevSlot = stackMap.get(place.Stack);
      if (prevSlot && prevSlot <= place.Pos) {
        // We already have a higher slot in this stack.
      } else {
        stackMap.set(place.Stack, place.Pos);
      }
    }

    // Now partition the stacks.
    const groups = [];           // Array of Group {name, src, sum, self, places}
    const groupMap = new Map();  // Map from Source to Group
    for (const place of places) {
      if (stackMap.get(place.Stack) != place.Pos) {
        continue;
      }

      const stack = stacks.Stacks[place.Stack];
      const src = stack.Sources[place.Pos];
      let group = groupMap.get(src);
      if (!group) {
        const name = stacks.Sources[src].FullName;
        group = {name: name, src: src, sum: 0, self: 0, places: []};
        groupMap.set(src, group);
        groups.push(group);
      }
      group.sum += stack.Value;
      group.self += (place.Pos == stack.Sources.length-1) ? stack.Value : 0;
      group.places.push(place);
    }

    // Order by decreasing cost (makes it easier to spot heavy functions).
    // Though alphabetical ordering is a potential alternative that will make
    // profile comparisons easier.
    groups.sort(function(a, b) { return b.sum - a.sum; });

    return groups;
  }

  function display(list) {
    // Sort boxes so that text selection follows a predictable order.
    list.sort(function(a, b) {
      if (a.y != b.y) return a.y - b.y;
      return a.x - b.x;
    });

    // Adjust Y coordinates so that zero is at top.
    let adjust = (list.length > 0) ? list[0].y : 0;
    adjust -= ROW + 2*PADDING;  // Room for details

    const divs = [];
    for (const box of list) {
      box.y -= adjust;
      divs.push(drawBox(box));
    }
    divs.push(drawSep(-adjust));

    const h = (list.length > 0 ?  list[list.length-1].y : 0) + 4*ROW;
    chart.style.height = h+'px';
    chart.replaceChildren(...divs);
  }

  function drawBox(box) {
    const srcIndex = box.src;
    const src = stacks.Sources[srcIndex];

    // Background
    const w = box.width - 1; // Leave 1px gap
    const r = document.createElement('div');
    r.style.left = box.x + 'px';
    r.style.top = box.y + 'px';
    r.style.width = w + 'px';
    r.style.height = (ROW-1) + 'px';  // Leave 1px gap
    r.classList.add('boxbg');
    r.style.background = makeColor(src.Color);
    addElem(srcIndex, r);

    // Box that shows time spent in self
    if (box.selfWidth >= MIN_WIDTH) {
      const s = document.createElement('div');
      s.style.width = Math.min(box.selfWidth, w)+'px';
      s.style.height = (ROW-1)+'px';
      s.classList.add('self');
      r.appendChild(s);
    }

    // Label
    if (box.width >= MIN_TEXT_WIDTH) {
      const t = document.createElement('div');
      t.classList.add('boxtext');
      fitText(t, box.width-2*TEXT_MARGIN, src.Display);
      r.appendChild(t);
    }

    r.addEventListener('click', () => { switchPivots(src.RE); });
    r.addEventListener('mouseenter', () => { handleEnter(box, r); });
    r.addEventListener('mouseleave', () => { handleLeave(box); });
    r.addEventListener('contextmenu', (e) => { showActionMenu(e, box); });
    return r;
  }

  function drawSep(y) {
    const m = document.createElement('div');
    m.innerText = percent(shownTotal, stacks.Total) +
	'\xa0\xa0\xa0\xa0' +  // Some non-breaking spaces
	valueString(shownTotal);
    m.style.top = (y-ROW) + 'px';
    m.style.left = PADDING + 'px';
    m.style.width = (chart.clientWidth - PADDING*2) + 'px';
    m.classList.add('separator');
    return m;
  }

  // addElem registers an element that belongs to the specified src.
  function addElem(src, elem) {
    let list = elems.get(src);
    if (!list) {
      list = [];
      elems.set(src, list);
    }
    list.push(elem);
    elem.classList.toggle('hilite', matches.has(src));
  }

  // Adds or removes cl from classList of all elements for the specified source.
  function toggleClass(src, cl, value) {
    const list = elems.get(src);
    if (list) {
      for (const elem of list) {
        elem.classList.toggle(cl, value);
      }
    }
  }

  // fitText sets text and font-size clipped to the specified width w.
  function fitText(t, avail, textList) {
    // Find first entry in textList that fits.
    let width = avail;
    textContext.font = FONT_SIZE + 'pt Arial';
    for (let i = 0; i < textList.length; i++) {
      let text = textList[i];
      width = textContext.measureText(text).width;
      if (width <= avail) {
        t.innerText = text;
        return;
      }
    }

    // Try to fit by dropping font size.
    let text = textList[textList.length-1];
    const fs = Math.max(MIN_FONT_SIZE, FONT_SIZE * (avail / width));
    t.style.fontSize = fs + 'pt';
    t.innerText = text;
  }

  // totalValue returns the combined sum of the stacks listed in places.
  function totalValue(places) {
    const seen = new Set();
    let result = 0;
    for (const place of places) {
      if (seen.has(place.Stack)) continue; // Do not double-count stacks
      seen.add(place.Stack);
      const stack = stacks.Stacks[place.Stack];
      result += stack.Value;
    }
    return result;
  }

  function details(box) {
    // E.g., 10% 7s
    // or    10% 7s (3s self
    let result = percent(box.sum, stacks.Total) + ' ' + valueString(box.sum);
    if (box.selfValue > 0) {
      result += ` (${valueString(box.selfValue)} self)`;
    }
    return result;
  }

  function percent(v, total) {
    return Number(((100.0 * v) / total).toFixed(1)) + '%';
  }

  // valueString returns a formatted string to display for value.
  function valueString(value) {
    let v = value * stacks.Scale;
    // Rescale to appropriate display unit.
    let unit = stacks.Unit;
    const list = UNITS.get(unit);
    if (list) {
      // Find first entry in list that is not too small.
      for (const [name, scale] of list) {
        if (v <= 100*scale) {
          v /= scale;
          unit = name;
          break;
        }
      }
    }
    return Number(v.toFixed(2)) + unit;
  }

  function find(name) {
    const elem = document.getElementById(name);
    if (!elem) {
      throw 'element not found: ' + name
    }
    return elem;
  }

  function makeColor(index) {
    // Rotate hue around a circle. Multiple by phi to spread things
    // out better. Use 50% saturation to make subdued colors, and
    // 80% lightness to have good contrast with black foreground text.
    const PHI = 1.618033988;
    const hue = (index+1) * PHI * 2 * Math.PI; // +1 to avoid 0
    const hsl = `hsl(${hue}rad 50% 80%)`;
    return hsl;
  }
}
