<html>
<!--
Copyright 2016 the V8 project authors. All rights reserved.  Use of this source
code is governed by a BSD-style license that can be found in the LICENSE file.
-->

<head>
<style>
  html {
    font-family: monospace;
  }

  .parse {
    background-color: red;
    border: 1px red solid;
  }

  .preparse {
    background-color: orange;
    border: 1px orange solid;
  }

  .resolution {
    background-color: green;
    border: 1px green solid;
  }

  .execution {
    background-color: black;
    border-left: 2px black solid;
    z-index: -1;
  }

  .script {
    margin-top: 1em;
    overflow: visible;
    clear: both;
      border-top: 2px black dotted;
  }
  .script h3 {
    height: 20px;
    margin-bottom: 0.5em;
    white-space: nowrap;
  }

  .script-details {
    float: left;
  }

  .chart {
    float: left;
    margin-right: 2em;
  }

  .funktion-list {
    float: left;
    height: 400px;
  }

  .funktion-list > ul {
    height: 80%;
    overflow-y: scroll;
  }


  .funktion {
  }

</style>
<script src="./splaytree.js" type="text/javascript"></script>
<script src="./codemap.js" type="text/javascript"></script>
<script src="./csvparser.js" type="text/javascript"></script>
<script src="./consarray.js" type="text/javascript"></script>
<script src="./profile.js" type="text/javascript"></script>
<script src="./profile_view.js" type="text/javascript"></script>
<script src="./logreader.js" type="text/javascript"></script>
<script src="./arguments.js" type="text/javascript"></script>
<script src="./parse-processor.js" type="text/javascript"></script>
<script src="./SourceMap.js" type="text/javascript"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
"use strict";
google.charts.load('current', {packages: ['corechart']});

function $(query) {
  return document.querySelector(query);
}


function loadFile() {
  let files = $('#uploadInput').files;

  let file = files[0];
  let reader = new FileReader();

  reader.onload = function(evt) {
    const kTimerName = 'parse log file';
    console.time(kTimerName);
    let parseProcessor = new ParseProcessor();
    parseProcessor.processString(this.result);
    console.timeEnd(kTimerName);
    renderParseResults(parseProcessor);
    document.parseProcessor = parseProcessor;
  }
  reader.readAsText(file);
}

function handleOnLoad() {
  document.querySelector("#uploadInput").focus();
}

function createNode(tag, classNames) {
  let node = document.createElement(tag);
  if (classNames) {
    if (Array.isArray(classNames)) {
      node.classList.add(...classNames);
    } else {
      node.className = classNames;
    }
  }
  return node;
}

function div(...args) {
  return createNode('div', ...args);
}

function h1(string) {
  let node = createNode('h1');
  node.appendChild(text(string));
  return node;
}

function h3(string, ...args) {
  let node = createNode('h3', ...args);
  if (string) node.appendChild(text(string));
  return node;
}

function a(href, string, ...args) {
  let link = createNode('a', ...args);
  if (href.length) link.href = href;
  if (string) link.appendChild(text(string));
  return link;
}

function text(string) {
  return document.createTextNode(string);
}

function delay(t) {
  return new Promise(resolve = > setTimeout(resolve, t));
}

function renderParseResults(parseProcessor) {
  let result = $('#result');
  // clear out all existing result pages;
  result.innerHTML = '';
  const start = parseProcessor.firstEvent;
  const end = parseProcessor.lastEvent;
  renderScript(result, parseProcessor.totalScript, start, end);
  // Build up the graphs lazily to keep the page responsive.
  parseProcessor.scripts.forEach(
      script => renderScript(result, script, start, end));
  // Install an intersection observer to lazily load the graphs when the script
  // div becomes visible for the first time.
  var io = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {
      if (entry.intersectionRatio == 0) return;
      console.assert(!entry.target.querySelector('.graph'));
      let target = entry.target;
      appendGraph(target.script, target, start, end);
      observer.unobserve(entry.target);
    });
  }, {});
  document.querySelectorAll('.script').forEach(div => io.observe(div));
}


const kTimeFactor = 10;
const kHeight = 20;
const kFunktionTopOffset = 50;

function renderScript(result, script, start, end) {
  // Filter out empty scripts.
  if (script.isEmpty() || script.lastParseEvent == 0) return;

  let scriptDiv = div('script');
  scriptDiv.script = script;

  let scriptTitle = h3();
  if (script.file) scriptTitle.appendChild(a(script.file, script.file));
  let anchor = a("", ' id=' + script.id);
  anchor.name = "script"+script.id
  scriptTitle.appendChild(anchor);
  scriptDiv.appendChild(scriptTitle);
  let summary = createNode('pre', 'script-details');
  summary.appendChild(text(script.summary));
  scriptDiv.appendChild(summary);
  result.appendChild(scriptDiv);
  return scriptDiv;
}

const kMaxTime = 120 * kSecondsToMillis;
// Resolution of the graphs
const kTimeIncrement = 1;
const kSelectionTimespan = 2;
const series = [
//    ['firstParseEvent', 'Any Parse Event'],
    ['parse', 'Parsing'],
//    ['preparse', 'Preparsing'],
//    ['resolution', 'Preparsing with Var. Resolution'],
    ['lazyCompile', 'Lazy Compilation'],
    ['compile', 'Eager Compilation'],
    ['execution', 'First Execution'],
];
const metricNames = series.map(each => each[0]);


function appendGraph(script, parentNode, start, end) {
  const timerLabel = 'graph script=' + script.id;
  // TODO(cbruni): add support for network events

  console.time(timerLabel);
  let data = new google.visualization.DataTable();
  data.addColumn('number', 'Time');
  // The series are interleave bytes processed, time spent and thus have two
  // different vAxes.
  let seriesOptions = [];
  series.forEach(each => {
    let description = each[1];
    // Add the bytes column.
    data.addColumn('number', description + ' Bytes');
    seriesOptions.push({targetAxisIndex: 0});
    // Add the time column.
    data.addColumn('number', description + ' Time');
    seriesOptions.push({targetAxisIndex: 1, lineDashStyle: [3, 2]});
  });
  // The first entry contains the total.
  seriesOptions[0].type = 'area';

  const maxTime = Math.min(kMaxTime, end);
  console.time('metrics');
  let metricValues =
    script.getAccumulatedTimeMetrics(metricNames , 0, maxTime, kTimeIncrement);
  console.timeEnd('metrics');
  console.assert(metricValues[0].length == seriesOptions.length + 1);
  data.addRows(metricValues);

  let options = {
    explorer: {
      actions: ['dragToZoom', 'rightClickToReset'],
      maxZoomIn: 0.01
    },
    hAxis: {
      format: '#,###.##s'
    },
    vAxes: {
      0: {title: 'Bytes Touched', format: 'short'},
      1: {title: 'Time', format: '#,###ms'}
    },
    height: 400,
    width: 1000,
    chartArea: {left: '5%', top: '15%', width: "85%", height: "75%"},
    // The first series should be a area chart (total bytes touched),
    series: seriesOptions,
    // everthing else is a line.
    seriesType: 'line'
  };
  let graphNode = createNode('div', 'chart');
  let listNode = createNode('div', 'funktion-list');
  parentNode.appendChild(graphNode);
  parentNode.appendChild(listNode);
  let chart = new google.visualization.ComboChart(graphNode);
  google.visualization.events.addListener(chart, 'select',
      () => selectGraphPointHandler(chart, data, script, parentNode));
  chart.draw(data, options);
  console.timeEnd(timerLabel);
}


function selectGraphPointHandler(chart, data, script, parentNode) {
  let selection = chart.getSelection();
  if (selection.length <= 0) return;
  // Display a list of funktions with events at the given time.
  let {row, column} = selection[0];
  if (row === null|| column === null) return;
  let name = series[((column-1)/2) | 0][0];
  let time = data.getValue(row, 0);
  let funktions = script.getFunktionsAtTime(
        time * kSecondsToMillis, kSelectionTimespan, name);
  let oldList = parentNode.querySelector('.funktion-list');
  parentNode.replaceChild(createFunktionList(name, time, funktions), oldList);
}

function createFunktionList(metric, time, funktions) {
  let container = createNode('div', 'funktion-list');
  container.appendChild(h3('Changes of ' + metric + ' at ' +
        time + 's: ' + funktions.length));
  let listNode = createNode('ul');
  funktions.forEach(funktion => {
    let node = createNode('li', 'funktion');
    node.funktion = funktion;
    node.appendChild(text(funktion.toString(false) + " "));
    let script = funktion.script;
    if (script) {
      node.appendChild(a("#script" + script.id, "in script " + script.id));
    }
    listNode.appendChild(node);
  });
  container.appendChild(listNode);
  return container;
}


</script>
</head>

<body onload="handleOnLoad()">
  <h1>BEHOLD, THIS IS PARSEROR!</h1>

  <h2>Usage</h2>
  Run your script with <code>--log-function-events</code> and upload <code>v8.log</code> on this page:<br/>
  <code>/path/to/d8 --log-function-events your_script.js</code>

  <h2>Data</h2>
  <form name="fileForm">
    <p>
      <input id="uploadInput" type="file" name="files" onchange="loadFile();"> trace entries: <span id="count">0</span>
    </p>
  </form>

  <h2>Result</h2>
  <div id="result"></div>
</body>

</html>
