// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package driver

import "html/template"

import "github.com/google/pprof/third_party/d3"
import "github.com/google/pprof/third_party/d3flamegraph"

// addTemplates adds a set of template definitions to templates.
func addTemplates(templates *template.Template) {
	template.Must(templates.Parse(`{{define "d3script"}}` + d3.JSSource + `{{end}}`))
	template.Must(templates.Parse(`{{define "d3flamegraphscript"}}` + d3flamegraph.JSSource + `{{end}}`))
	template.Must(templates.Parse(`{{define "d3flamegraphcss"}}` + d3flamegraph.CSSSource + `{{end}}`))
	template.Must(templates.Parse(`
{{define "css"}}
<style type="text/css">
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
html, body {
  height: 100%;
}
body {
  font-family: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
  font-size: 13px;
  line-height: 1.4;
  display: flex;
  flex-direction: column;
}
a {
  color: #2a66d9;
}
.header {
  display: flex;
  align-items: center;
  height: 44px;
  min-height: 44px;
  background-color: #eee;
  color: #212121;
  padding: 0 1rem;
}
.header > div {
  margin: 0 0.125em;
}
.header .title h1 {
  font-size: 1.75em;
  margin-right: 1rem;
}
.header .title a {
  color: #212121;
  text-decoration: none;
}
.header .title a:hover {
  text-decoration: underline;
}
.header .description {
  width: 100%;
  text-align: right;
  white-space: nowrap;
}
@media screen and (max-width: 799px) {
  .header input {
    display: none;
  }
}
#detailsbox {
  display: none;
  z-index: 1;
  position: fixed;
  top: 40px;
  right: 20px;
  background-color: #ffffff;
  box-shadow: 0 1px 5px rgba(0,0,0,.3);
  line-height: 24px;
  padding: 1em;
  text-align: left;
}
.header input {
  background: white url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' style='pointer-events:none;display:block;width:100%25;height:100%25;fill:#757575'%3E%3Cpath d='M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61.0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z'/%3E%3C/svg%3E") no-repeat 4px center/20px 20px;
  border: 1px solid #d1d2d3;
  border-radius: 2px 0 0 2px;
  padding: 0.25em;
  padding-left: 28px;
  margin-left: 1em;
  font-family: 'Roboto', 'Noto', sans-serif;
  font-size: 1em;
  line-height: 24px;
  color: #212121;
}
.downArrow {
  border-top: .36em solid #ccc;
  border-left: .36em solid transparent;
  border-right: .36em solid transparent;
  margin-bottom: .05em;
  margin-left: .5em;
  transition: border-top-color 200ms;
}
.menu-item {
  height: 100%;
  text-transform: uppercase;
  font-family: 'Roboto Medium', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
  position: relative;
}
.menu-item .menu-name:hover {
  opacity: 0.75;
}
.menu-item .menu-name:hover .downArrow {
  border-top-color: #666;
}
.menu-name {
  height: 100%;
  padding: 0 0.5em;
  display: flex;
  align-items: center;
  justify-content: center;
}
.submenu {
  display: none;
  z-index: 1;
  margin-top: -4px;
  min-width: 10em;
  position: absolute;
  left: 0px;
  background-color: white;
  box-shadow: 0 1px 5px rgba(0,0,0,.3);
  font-size: 100%;
  text-transform: none;
}
.menu-item, .submenu {
  user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -webkit-user-select: none;
}
.submenu hr {
  border: 0;
  border-top: 2px solid #eee;
}
.submenu a {
  display: block;
  padding: .5em 1em;
  text-decoration: none;
}
.submenu a:hover, .submenu a.active {
  color: white;
  background-color: #6b82d6;
}
.submenu a.disabled {
  color: gray;
  pointer-events: none;
}

#content {
  overflow-y: scroll;
  padding: 1em;
}
#top {
  overflow-y: scroll;
}
#graph {
  overflow: hidden;
}
#graph svg {
  width: 100%;
  height: auto;
  padding: 10px;
}
#content.source .filename {
  margin-top: 0;
  margin-bottom: 1em;
  font-size: 120%;
}
#content.source pre {
  margin-bottom: 3em;
}
table {
  border-spacing: 0px;
  width: 100%;
  padding-bottom: 1em;
  white-space: nowrap;
}
table thead {
  font-family: 'Roboto Medium', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
}
table tr th {
  background-color: #ddd;
  text-align: right;
  padding: .3em .5em;
}
table tr td {
  padding: .3em .5em;
  text-align: right;
}
#top table tr th:nth-child(6),
#top table tr th:nth-child(7),
#top table tr td:nth-child(6),
#top table tr td:nth-child(7) {
  text-align: left;
}
#top table tr td:nth-child(6) {
  width: 100%;
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}
#flathdr1, #flathdr2, #cumhdr1, #cumhdr2, #namehdr {
  cursor: ns-resize;
}
.hilite {
  background-color: #ebf5fb;
  font-weight: bold;
}
</style>
{{end}}

{{define "header"}}
<div class="header">
  <div class="title">
    <h1><a href="./">pprof</a></h1>
  </div>

  <div id="view" class="menu-item">
    <div class="menu-name">
      View
      <i class="downArrow"></i>
    </div>
    <div class="submenu">
      <a title="{{.Help.top}}"  href="./top" id="topbtn">Top</a>
      <a title="{{.Help.graph}}" href="./" id="graphbtn">Graph</a>
      <a title="{{.Help.flamegraph}}" href="./flamegraph" id="flamegraph">Flame Graph</a>
      <a title="{{.Help.peek}}" href="./peek" id="peek">Peek</a>
      <a title="{{.Help.list}}" href="./source" id="list">Source</a>
      <a title="{{.Help.disasm}}" href="./disasm" id="disasm">Disassemble</a>
    </div>
  </div>

  <div id="refine" class="menu-item">
    <div class="menu-name">
      Refine
      <i class="downArrow"></i>
    </div>
    <div class="submenu">
      <a title="{{.Help.focus}}" href="?" id="focus">Focus</a>
      <a title="{{.Help.ignore}}" href="?" id="ignore">Ignore</a>
      <a title="{{.Help.hide}}" href="?" id="hide">Hide</a>
      <a title="{{.Help.show}}" href="?" id="show">Show</a>
      <hr>
      <a title="{{.Help.reset}}" href="?">Reset</a>
    </div>
  </div>

  <div>
    <input id="search" type="text" placeholder="Search regexp" autocomplete="off" autocapitalize="none" size=40>
  </div>

  <div class="description">
    <a title="{{.Help.details}}" href="#" id="details">{{.Title}}</a>
    <div id="detailsbox">
      {{range .Legend}}<div>{{.}}</div>{{end}}
    </div>
  </div>
</div>

<div id="errors">{{range .Errors}}<div>{{.}}</div>{{end}}</div>
{{end}}

{{define "graph" -}}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>{{.Title}}</title>
  {{template "css" .}}
</head>
<body>
  {{template "header" .}}
  <div id="graph">
    {{.HTMLBody}}
  </div>
  {{template "script" .}}
  <script>viewer(new URL(window.location.href), {{.Nodes}});</script>
</body>
</html>
{{end}}

{{define "script"}}
<script>
// Make svg pannable and zoomable.
// Call clickHandler(t) if a click event is caught by the pan event handlers.
function initPanAndZoom(svg, clickHandler) {
  'use strict';

  // Current mouse/touch handling mode
  const IDLE = 0;
  const MOUSEPAN = 1;
  const TOUCHPAN = 2;
  const TOUCHZOOM = 3;
  let mode = IDLE;

  // State needed to implement zooming.
  let currentScale = 1.0;
  const initWidth = svg.viewBox.baseVal.width;
  const initHeight = svg.viewBox.baseVal.height;

  // State needed to implement panning.
  let panLastX = 0;      // Last event X coordinate
  let panLastY = 0;      // Last event Y coordinate
  let moved = false;     // Have we seen significant movement
  let touchid = null;    // Current touch identifier

  // State needed for pinch zooming
  let touchid2 = null;     // Second id for pinch zooming
  let initGap = 1.0;       // Starting gap between two touches
  let initScale = 1.0;     // currentScale when pinch zoom started
  let centerPoint = null;  // Center point for scaling

  // Convert event coordinates to svg coordinates.
  function toSvg(x, y) {
    const p = svg.createSVGPoint();
    p.x = x;
    p.y = y;
    let m = svg.getCTM();
    if (m == null) m = svg.getScreenCTM(); // Firefox workaround.
    return p.matrixTransform(m.inverse());
  }

  // Change the scaling for the svg to s, keeping the point denoted
  // by u (in svg coordinates]) fixed at the same screen location.
  function rescale(s, u) {
    // Limit to a good range.
    if (s < 0.2) s = 0.2;
    if (s > 10.0) s = 10.0;

    currentScale = s;

    // svg.viewBox defines the visible portion of the user coordinate
    // system.  So to magnify by s, divide the visible portion by s,
    // which will then be stretched to fit the viewport.
    const vb = svg.viewBox;
    const w1 = vb.baseVal.width;
    const w2 = initWidth / s;
    const h1 = vb.baseVal.height;
    const h2 = initHeight / s;
    vb.baseVal.width = w2;
    vb.baseVal.height = h2;

    // We also want to adjust vb.baseVal.x so that u.x remains at same
    // screen X coordinate.  In other words, want to change it from x1 to x2
    // so that:
    //     (u.x - x1) / w1 = (u.x - x2) / w2
    // Simplifying that, we get
    //     (u.x - x1) * (w2 / w1) = u.x - x2
    //     x2 = u.x - (u.x - x1) * (w2 / w1)
    vb.baseVal.x = u.x - (u.x - vb.baseVal.x) * (w2 / w1);
    vb.baseVal.y = u.y - (u.y - vb.baseVal.y) * (h2 / h1);
  }

  function handleWheel(e) {
    if (e.deltaY == 0) return;
    // Change scale factor by 1.1 or 1/1.1
    rescale(currentScale * (e.deltaY < 0 ? 1.1 : (1/1.1)),
            toSvg(e.offsetX, e.offsetY));
  }

  function setMode(m) {
    mode = m;
    touchid = null;
    touchid2 = null;
  }

  function panStart(x, y) {
    moved = false;
    panLastX = x;
    panLastY = y;
  }

  function panMove(x, y) {
    let dx = x - panLastX;
    let dy = y - panLastY;
    if (Math.abs(dx) <= 2 && Math.abs(dy) <= 2) return; // Ignore tiny moves

    moved = true;
    panLastX = x;
    panLastY = y;

    // Firefox workaround: get dimensions from parentNode.
    const swidth = svg.clientWidth || svg.parentNode.clientWidth;
    const sheight = svg.clientHeight || svg.parentNode.clientHeight;

    // Convert deltas from screen space to svg space.
    dx *= (svg.viewBox.baseVal.width / swidth);
    dy *= (svg.viewBox.baseVal.height / sheight);

    svg.viewBox.baseVal.x -= dx;
    svg.viewBox.baseVal.y -= dy;
  }

  function handleScanStart(e) {
    if (e.button != 0) return; // Do not catch right-clicks etc.
    setMode(MOUSEPAN);
    panStart(e.clientX, e.clientY);
    e.preventDefault();
    svg.addEventListener('mousemove', handleScanMove);
  }

  function handleScanMove(e) {
    if (e.buttons == 0) {
      // Missed an end event, perhaps because mouse moved outside window.
      setMode(IDLE);
      svg.removeEventListener('mousemove', handleScanMove);
      return;
    }
    if (mode == MOUSEPAN) panMove(e.clientX, e.clientY);
  }

  function handleScanEnd(e) {
    if (mode == MOUSEPAN) panMove(e.clientX, e.clientY);
    setMode(IDLE);
    svg.removeEventListener('mousemove', handleScanMove);
    if (!moved) clickHandler(e.target);
  }

  // Find touch object with specified identifier.
  function findTouch(tlist, id) {
    for (const t of tlist) {
      if (t.identifier == id) return t;
    }
    return null;
  }

  // Return distance between two touch points
  function touchGap(t1, t2) {
    const dx = t1.clientX - t2.clientX;
    const dy = t1.clientY - t2.clientY;
    return Math.hypot(dx, dy);
  }

  function handleTouchStart(e) {
    if (mode == IDLE && e.changedTouches.length == 1) {
      // Start touch based panning
      const t = e.changedTouches[0];
      setMode(TOUCHPAN);
      touchid = t.identifier;
      panStart(t.clientX, t.clientY);
      e.preventDefault();
    } else if (mode == TOUCHPAN && e.touches.length == 2) {
      // Start pinch zooming
      setMode(TOUCHZOOM);
      const t1 = e.touches[0];
      const t2 = e.touches[1];
      touchid = t1.identifier;
      touchid2 = t2.identifier;
      initScale = currentScale;
      initGap = touchGap(t1, t2);
      centerPoint = toSvg((t1.clientX + t2.clientX) / 2,
                          (t1.clientY + t2.clientY) / 2);
      e.preventDefault();
    }
  }

  function handleTouchMove(e) {
    if (mode == TOUCHPAN) {
      const t = findTouch(e.changedTouches, touchid);
      if (t == null) return;
      if (e.touches.length != 1) {
        setMode(IDLE);
        return;
      }
      panMove(t.clientX, t.clientY);
      e.preventDefault();
    } else if (mode == TOUCHZOOM) {
      // Get two touches; new gap; rescale to ratio.
      const t1 = findTouch(e.touches, touchid);
      const t2 = findTouch(e.touches, touchid2);
      if (t1 == null || t2 == null) return;
      const gap = touchGap(t1, t2);
      rescale(initScale * gap / initGap, centerPoint);
      e.preventDefault();
    }
  }

  function handleTouchEnd(e) {
    if (mode == TOUCHPAN) {
      const t = findTouch(e.changedTouches, touchid);
      if (t == null) return;
      panMove(t.clientX, t.clientY);
      setMode(IDLE);
      e.preventDefault();
      if (!moved) clickHandler(t.target);
    } else if (mode == TOUCHZOOM) {
      setMode(IDLE);
      e.preventDefault();
    }
  }

  svg.addEventListener('mousedown', handleScanStart);
  svg.addEventListener('mouseup', handleScanEnd);
  svg.addEventListener('touchstart', handleTouchStart);
  svg.addEventListener('touchmove', handleTouchMove);
  svg.addEventListener('touchend', handleTouchEnd);
  svg.addEventListener('wheel', handleWheel, true);
}

function initMenus() {
  'use strict';

  let activeMenu = null;
  let activeMenuHdr = null;

  function cancelActiveMenu() {
    if (activeMenu == null) return;
    activeMenu.style.display = 'none';
    activeMenu = null;
    activeMenuHdr = null;
  }

  // Set click handlers on every menu header.
  for (const menu of document.getElementsByClassName('submenu')) {
    const hdr = menu.parentElement;
    if (hdr == null) return;
    if (hdr.classList.contains('disabled')) return;
    function showMenu(e) {
      // menu is a child of hdr, so this event can fire for clicks
      // inside menu. Ignore such clicks.
      if (e.target.parentElement != hdr) return;
      activeMenu = menu;
      activeMenuHdr = hdr;
      menu.style.display = 'block';
    }
    hdr.addEventListener('mousedown', showMenu);
    hdr.addEventListener('touchstart', showMenu);
  }

  // If there is an active menu and a down event outside, retract the menu.
  for (const t of ['mousedown', 'touchstart']) {
    document.addEventListener(t, (e) => {
      // Note: to avoid unnecessary flicker, if the down event is inside
      // the active menu header, do not retract the menu.
      if (activeMenuHdr != e.target.closest('.menu-item')) {
        cancelActiveMenu();
      }
    }, { passive: true, capture: true });
  }

  // If there is an active menu and an up event inside, retract the menu.
  document.addEventListener('mouseup', (e) => {
    if (activeMenu == e.target.closest('.submenu')) {
      cancelActiveMenu();
    }
  }, { passive: true, capture: true });
}

function viewer(baseUrl, nodes) {
  'use strict';

  // Elements
  const search = document.getElementById('search');
  const graph0 = document.getElementById('graph0');
  const svg = (graph0 == null ? null : graph0.parentElement);
  const toptable = document.getElementById('toptable');

  let regexpActive = false;
  let selected = new Map();
  let origFill = new Map();
  let searchAlarm = null;
  let buttonsEnabled = true;

  function handleDetails(e) {
    e.preventDefault();
    const detailsText = document.getElementById('detailsbox');
    if (detailsText != null) {
      if (detailsText.style.display === 'block') {
        detailsText.style.display = 'none';
      } else {
        detailsText.style.display = 'block';
      }
    }
  }

  function handleKey(e) {
    if (e.keyCode != 13) return;
    window.location.href =
        updateUrl(new URL(window.location.href), 'f');
    e.preventDefault();
  }

  function handleSearch() {
    // Delay expensive processing so a flurry of key strokes is handled once.
    if (searchAlarm != null) {
      clearTimeout(searchAlarm);
    }
    searchAlarm = setTimeout(selectMatching, 300);

    regexpActive = true;
    updateButtons();
  }

  function selectMatching() {
    searchAlarm = null;
    let re = null;
    if (search.value != '') {
      try {
        re = new RegExp(search.value);
      } catch (e) {
        // TODO: Display error state in search box
        return;
      }
    }

    function match(text) {
      return re != null && re.test(text);
    }

    // drop currently selected items that do not match re.
    selected.forEach(function(v, n) {
      if (!match(nodes[n])) {
        unselect(n, document.getElementById('node' + n));
      }
    })

    // add matching items that are not currently selected.
    for (let n = 0; n < nodes.length; n++) {
      if (!selected.has(n) && match(nodes[n])) {
        select(n, document.getElementById('node' + n));
      }
    }

    updateButtons();
  }

  function toggleSvgSelect(elem) {
    // Walk up to immediate child of graph0
    while (elem != null && elem.parentElement != graph0) {
      elem = elem.parentElement;
    }
    if (!elem) return;

    // Disable regexp mode.
    regexpActive = false;

    const n = nodeId(elem);
    if (n < 0) return;
    if (selected.has(n)) {
      unselect(n, elem);
    } else {
      select(n, elem);
    }
    updateButtons();
  }

  function unselect(n, elem) {
    if (elem == null) return;
    selected.delete(n);
    setBackground(elem, false);
  }

  function select(n, elem) {
    if (elem == null) return;
    selected.set(n, true);
    setBackground(elem, true);
  }

  function nodeId(elem) {
    const id = elem.id;
    if (!id) return -1;
    if (!id.startsWith('node')) return -1;
    const n = parseInt(id.slice(4), 10);
    if (isNaN(n)) return -1;
    if (n < 0 || n >= nodes.length) return -1;
    return n;
  }

  function setBackground(elem, set) {
    // Handle table row highlighting.
    if (elem.nodeName == 'TR') {
      elem.classList.toggle('hilite', set);
      return;
    }

    // Handle svg element highlighting.
    const p = findPolygon(elem);
    if (p != null) {
      if (set) {
        origFill.set(p, p.style.fill);
        p.style.fill = '#ccccff';
      } else if (origFill.has(p)) {
        p.style.fill = origFill.get(p);
      }
    }
  }

  function findPolygon(elem) {
    if (elem.localName == 'polygon') return elem;
    for (const c of elem.children) {
      const p = findPolygon(c);
      if (p != null) return p;
    }
    return null;
  }

  // convert a string to a regexp that matches that string.
  function quotemeta(str) {
    return str.replace(/([\\\.?+*\[\](){}|^$])/g, '\\$1');
  }

  // Update id's href to reflect current selection whenever it is
  // liable to be followed.
  function makeLinkDynamic(id) {
    const elem = document.getElementById(id);
    if (elem == null) return;

    // Most links copy current selection into the 'f' parameter,
    // but Refine menu links are different.
    let param = 'f';
    if (id == 'ignore') param = 'i';
    if (id == 'hide') param = 'h';
    if (id == 'show') param = 's';

    // We update on mouseenter so middle-click/right-click work properly.
    elem.addEventListener('mouseenter', updater);
    elem.addEventListener('touchstart', updater);

    function updater() {
      elem.href = updateUrl(new URL(elem.href), param);
    }
  }

  // Update URL to reflect current selection.
  function updateUrl(url, param) {
    url.hash = '';

    // The selection can be in one of two modes: regexp-based or
    // list-based.  Construct regular expression depending on mode.
    let re = regexpActive
      ? search.value
      : Array.from(selected.keys()).map(key => quotemeta(nodes[key])).join('|');

    // 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]);
    }

    if (re != '') {
      // For focus/show, forget old parameter.  For others, add to re.
      if (param != 'f' && param != 's' && params.has(param)) {
        const old = params.get(param);
         if (old != '') {
          re += '|' + old;
        }
      }
      params.set(param, re);
    } else {
      params.delete(param);
    }

    return url.toString();
  }

  function handleTopClick(e) {
    // Walk back until we find TR and then get the Name column (index 5)
    let elem = e.target;
    while (elem != null && elem.nodeName != 'TR') {
      elem = elem.parentElement;
    }
    if (elem == null || elem.children.length < 6) return;

    e.preventDefault();
    const tr = elem;
    const td = elem.children[5];
    if (td.nodeName != 'TD') return;
    const name = td.innerText;
    const index = nodes.indexOf(name);
    if (index < 0) return;

    // Disable regexp mode.
    regexpActive = false;

    if (selected.has(index)) {
      unselect(index, elem);
    } else {
      select(index, elem);
    }
    updateButtons();
  }

  function updateButtons() {
    const enable = (search.value != '' || selected.size != 0);
    if (buttonsEnabled == enable) return;
    buttonsEnabled = enable;
    for (const id of ['focus', 'ignore', 'hide', 'show']) {
      const link = document.getElementById(id);
      if (link != null) {
        link.classList.toggle('disabled', !enable);
      }
    }
  }

  // Initialize button states
  updateButtons();

  // Setup event handlers
  initMenus();
  if (svg != null) {
    initPanAndZoom(svg, toggleSvgSelect);
  }
  if (toptable != null) {
    toptable.addEventListener('mousedown', handleTopClick);
    toptable.addEventListener('touchstart', handleTopClick);
  }

  const ids = ['topbtn', 'graphbtn', 'peek', 'list', 'disasm',
               'focus', 'ignore', 'hide', 'show'];
  ids.forEach(makeLinkDynamic);

  // Bind action to button with specified id.
  function addAction(id, action) {
    const btn = document.getElementById(id);
    if (btn != null) {
      btn.addEventListener('click', action);
      btn.addEventListener('touchstart', action);
    }
  }

  addAction('details', handleDetails);

  search.addEventListener('input', handleSearch);
  search.addEventListener('keydown', handleKey);

  // Give initial focus to main container so it can be scrolled using keys.
  const main = document.getElementById('bodycontainer');
  if (main) {
    main.focus();
  }
}
</script>
{{end}}

{{define "top" -}}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>{{.Title}}</title>
  {{template "css" .}}
  <style type="text/css">
  </style>
</head>
<body>
  {{template "header" .}}
  <div id="top">
    <table id="toptable">
      <thead>
        <tr>
          <th id="flathdr1">Flat</th>
          <th id="flathdr2">Flat%</th>
          <th>Sum%</th>
          <th id="cumhdr1">Cum</th>
          <th id="cumhdr2">Cum%</th>
          <th id="namehdr">Name</th>
          <th>Inlined?</th>
        </tr>
      </thead>
      <tbody id="rows"></tbody>
    </table>
  </div>
  {{template "script" .}}
  <script>
    function makeTopTable(total, entries) {
      const rows = document.getElementById('rows');
      if (rows == null) return;

      // Store initial index in each entry so we have stable node ids for selection.
      for (let i = 0; i < entries.length; i++) {
        entries[i].Id = 'node' + i;
      }

      // Which column are we currently sorted by and in what order?
      let currentColumn = '';
      let descending = false;
      sortBy('Flat');

      function sortBy(column) {
        // Update sort criteria
        if (column == currentColumn) {
          descending = !descending; // Reverse order
        } else {
          currentColumn = column;
          descending = (column != 'Name');
        }

        // Sort according to current criteria.
        function cmp(a, b) {
          const av = a[currentColumn];
          const bv = b[currentColumn];
          if (av < bv) return -1;
          if (av > bv) return +1;
          return 0;
        }
        entries.sort(cmp);
        if (descending) entries.reverse();

        function addCell(tr, val) {
          const td = document.createElement('td');
          td.textContent = val;
          tr.appendChild(td);
        }

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

        // Generate rows
        const fragment = document.createDocumentFragment();
        let sum = 0;
        for (const row of entries) {
          const tr = document.createElement('tr');
          tr.id = row.Id;
          sum += row.Flat;
          addCell(tr, row.FlatFormat);
          addCell(tr, percent(row.Flat));
          addCell(tr, percent(sum));
          addCell(tr, row.CumFormat);
          addCell(tr, percent(row.Cum));
          addCell(tr, row.Name);
          addCell(tr, row.InlineLabel);
          fragment.appendChild(tr);
        }

        rows.textContent = ''; // Remove old rows
        rows.appendChild(fragment);
      }

      // Make different column headers trigger sorting.
      function bindSort(id, column) {
        const hdr = document.getElementById(id);
        if (hdr == null) return;
        const fn = function() { sortBy(column) };
        hdr.addEventListener('click', fn);
        hdr.addEventListener('touch', fn);
      }
      bindSort('flathdr1', 'Flat');
      bindSort('flathdr2', 'Flat');
      bindSort('cumhdr1', 'Cum');
      bindSort('cumhdr2', 'Cum');
      bindSort('namehdr', 'Name');
    }

    viewer(new URL(window.location.href), {{.Nodes}});
    makeTopTable({{.Total}}, {{.Top}});
  </script>
</body>
</html>
{{end}}

{{define "sourcelisting" -}}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>{{.Title}}</title>
  {{template "css" .}}
  {{template "weblistcss" .}}
  {{template "weblistjs" .}}
</head>
<body>
  {{template "header" .}}
  <div id="content" class="source">
    {{.HTMLBody}}
  </div>
  {{template "script" .}}
  <script>viewer(new URL(window.location.href), null);</script>
</body>
</html>
{{end}}

{{define "plaintext" -}}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>{{.Title}}</title>
  {{template "css" .}}
</head>
<body>
  {{template "header" .}}
  <div id="content">
    <pre>
      {{.TextBody}}
    </pre>
  </div>
  {{template "script" .}}
  <script>viewer(new URL(window.location.href), null);</script>
</body>
</html>
{{end}}

{{define "flamegraph" -}}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>{{.Title}}</title>
  {{template "css" .}}
  <style type="text/css">{{template "d3flamegraphcss" .}}</style>
  <style type="text/css">
    .flamegraph-content {
      width: 90%;
      min-width: 80%;
      margin-left: 5%;
    }
    .flamegraph-details {
      height: 1.2em;
      width: 90%;
      min-width: 90%;
      margin-left: 5%;
      padding: 15px 0 35px;
    }
  </style>
</head>
<body>
  {{template "header" .}}
  <div id="bodycontainer">
    <div id="flamegraphdetails" class="flamegraph-details"></div>
    <div class="flamegraph-content">
      <div id="chart"></div>
    </div>
  </div>
  {{template "script" .}}
  <script>viewer(new URL(window.location.href), {{.Nodes}});</script>
  <script>{{template "d3script" .}}</script>
  <script>{{template "d3flamegraphscript" .}}</script>
  <script>
    var data = {{.FlameGraph}};

    var width = document.getElementById('chart').clientWidth;

    var flameGraph = d3.flamegraph()
      .width(width)
      .cellHeight(18)
      .minFrameSize(1)
      .transitionDuration(750)
      .transitionEase(d3.easeCubic)
      .inverted(true)
      .title('')
      .tooltip(false)
      .details(document.getElementById('flamegraphdetails'));

    // <full name> (percentage, value)
    flameGraph.label((d) => d.data.f + ' (' + d.data.p + ', ' + d.data.l + ')');

    (function(flameGraph) {
      var oldColorMapper = flameGraph.color();
      function colorMapper(d) {
        // Hack to force default color mapper to use 'warm' color scheme by not passing libtype
        const { data, highlight } = d;
        return oldColorMapper({ data: { n: data.n }, highlight });
      }

      flameGraph.color(colorMapper);
    }(flameGraph));

    d3.select('#chart')
      .datum(data)
      .call(flameGraph);

    function clear() {
      flameGraph.clear();
    }

    function resetZoom() {
      flameGraph.resetZoom();
    }

    window.addEventListener('resize', function() {
      var width = document.getElementById('chart').clientWidth;
      var graphs = document.getElementsByClassName('d3-flame-graph');
      if (graphs.length > 0) {
        graphs[0].setAttribute('width', width);
      }
      flameGraph.width(width);
      flameGraph.resetZoom();
    }, true);

    var search = document.getElementById('search');
    var searchAlarm = null;

    function selectMatching() {
      searchAlarm = null;

      if (search.value != '') {
        flameGraph.search(search.value);
      } else {
        flameGraph.clear();
      }
    }

    function handleSearch() {
      // Delay expensive processing so a flurry of key strokes is handled once.
      if (searchAlarm != null) {
        clearTimeout(searchAlarm);
      }
      searchAlarm = setTimeout(selectMatching, 300);
    }

    search.addEventListener('input', handleSearch);
  </script>
</body>
</html>
{{end}}
`))
}
