/**
 * @module module/explore-sk
 * @description <h2><code>explore-sk</code></h2>
 *
 * Main page of Perf, for exploring data.
 */
import { define } from 'elements-sk/define';
import { errorMessage } from 'elements-sk/errorMessage';
import { html } from 'lit-html';
import { jsonOrThrow } from 'common-sk/modules/jsonOrThrow';
import { stateReflector } from 'common-sk/modules/stateReflector';
import { toParamSet } from 'common-sk/modules/query';
import dialogPolyfill from 'dialog-polyfill';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';

import 'elements-sk/checkbox-sk';
import 'elements-sk/icon/help-icon-sk';
import 'elements-sk/spinner-sk';
import 'elements-sk/styles/buttons';
import 'elements-sk/tabs-panel-sk';
import 'elements-sk/tabs-sk';

import '../../../infra-sk/modules/query-sk';
import '../../../infra-sk/modules/paramset-sk';

import '../commit-detail-panel-sk';
import '../domain-picker-sk';
import '../json-source-sk';
import '../plot-simple-sk';
import '../query-count-sk';

// MISSING_DATA_SENTINEL signifies a missing sample value.
//
// JSON doesn't support NaN or +/- Inf, so we need a valid float32 to signal
// missing data that also has a compact JSON representation.
//
// The mirror Go definition is in infra/go/vec32.
const MISSING_DATA_SENTINEL = 1e32;

// The trace id of the zero line, a trace of all zeros.
const ZERO_NAME = 'special_zero';

// How often to refresh if the auto-refresh checkmark is checked.
const REFRESH_TIMEOUT = 30 * 1000; // milliseconds

// The default query range in seconds.
const DEFAULT_RANGE_S = 24 * 60 * 60; // 2 days in seconds.

// The index of the params tab.
const PARAMS_TAB_INDEX = 0;

// The index of the commit detail info tab.
const COMMIT_TAB_INDEX = 1;

// The percentage of the current zoom window to pan or zoom on a keypress.
const ZOOM_JUMP_PERCENT = 0.1;

// The minimum length [right - left] of a zoom range.
const MIN_ZOOM_RANGE = 0.1;

// TODO(jcgregorio) Move to a 'key' module.
// Returns true if paramName=paramValue appears in the given structured key.
function _matches(key, paramName, paramValue) {
  return key.indexOf(`,${paramName}=${paramValue},`) >= 0;
}

// TODO(jcgregorio) Move to a 'key' module.
// Parses the structured key and returns a populated object with all
// the param names and values.
function toObject(key) {
  const ret = {};
  key.split(',').forEach((s, i) => {
    if (i === 0) {
      return;
    }
    if (s === '') {
      return;
    }
    const parts = s.split('=');
    if (parts.length !== 2) {
      return;
    }
    ret[parts[0]] = parts[1];
  });
  return ret;
}

const template = (ele) => html`
  <div id=buttons>
    <button @click=${ele._openQuery}>Query</button>
    <div id=traceButtons ?hide_if_no_data=${!ele._hasData()}>
      <button @click=${() => ele._removeAll(false)} title='Remove all the traces.'>Remove All</button>
      <button @click=${ele._removeHighlighted} title='Remove all the highlighted traces.'>Remove Highlighted</button>
      <button @click=${ele._highlightedOnly} title='Remove all but the highlighted traces.'>Highlighted Only</button>
      <span title='Number of commits skipped between each point displayed.' ?hidden=${ele._isZero(ele._dataframe.skip)} id=skip>${ele._dataframe.skip}</span>
      <checkbox-sk name=zero @change=${ele._zeroChangeHandler} ?checked=${ele.state.show_zero} label='Zero' title='Toggle the presence of the zero line.'>Zero</checkbox-sk>
      <checkbox-sk name=auto @change=${ele._autoRefreshHandler} ?checked=${ele.state.auto_refresh} label='Auto-refresh'   title='Auto-refresh the data displayed in the graph.'>Auto-Refresh</checkbox-sk>
      <button @click=${ele._zoomToRange} ?disabled=${ele._zoomRange === null} title="Fit the time range to the current zoom window.">Zoom Range</button>
    </div>
  </div>

  <div id=spin-overlay>
    <plot-simple-sk
      summary
      width=1200
      height=400
      id=plot
      ?spinning=${ele.spinning}
      @trace_selected=${ele._traceSelected}
      @zoom=${ele._plotZoom}
      @trace_focused=${ele._plotTraceFocused}
      ?hide_if_no_data=${!ele._hasData()}
      >
    </plot-simple-sk>
    <div id=spin-container ?spinning=${ele.spinning}>
      <spinner-sk id=spinner ?active=${ele.spinning}></spinner-sk>
      <span id=percent></span>
    </div>
  </div>

  <div id=bottomButtons>
    <div id=shiftButtons ?hide_if_no_data=${!ele._hasData()}>
      <button @click=${ele._shiftLeft} title='Move ${ele._numShift} commits in the past.'>&lt;&lt; ${ele._numShift}</button>
      <button @click=${ele._shiftBoth} title='Expand the display ${ele._numShift} commits in both directions.'>&lt;&lt; ${+ele._numShift} &gt;&gt;</button>
      <button @click=${ele._shiftRight} title='Move ${ele._numShift} commits in the future.'>${+ele._numShift} &gt;&gt;</button>
    </div>
    <div id=calcButtons ?hide_if_no_data=${!ele._hasData()}>
      <button @click=${ele._normalize} title='Apply norm() to all the traces.'>Normalize</button>
      <button @click=${ele._scale_by_avg} title='Apply scale_by_avg() to all the traces.'>Scale By Avg</button>
      <button @click=${ele._csv} title='Download all displayed data as a CSV file.'>CSV</button>
        <a href='' target=_blank download='traces.csv' id=csv_download></a>
    </div>
  </div>

  <dialog id='query-dialog'>
    <h2>Query</h2>
    <div class=query-parts>
      <query-sk
        id=query
        @query-change=${ele._queryChangeHandler}
        @query-change-delayed=${ele._queryChangeDelayedHandler}
        ></query-sk>
        <div id=selections>
          <h3>Selections</h3>
          <paramset-sk id=summary></paramset-sk>
          <div class=query-counts>
            Matches: <query-count-sk url='/_/count/' @paramset-changed=${ele._paramsetChanged}>
            </query-count-sk>
          </div>
          <button @click=${() => ele._add(true)} class=action>Plot</button>
          <button @click=${() => ele._add(false)}>Add to Plot</button>
        </div>
    </div>
    <details>
      <summary><h2>Time Range</h2></summary>
      <domain-picker-sk id=range .state=${ele.state}>
      </domain-picker-sk>
    </details>

    <details>
      <summary><h2>Calculated Traces</h2></summary>
      <div class=formulas>
        <textarea id=formula rows=3 cols=80></textarea>
        <button @click=${() => ele._addCalculated(true)}>Plot</button>
        <button @click=${() => ele._addCalculated(false)}>Add to Plot</button>
        <a href=/help/ target=_blank>
          <help-icon-sk></help-icon-sk>
        </a>
      </div>
    </details>
  </dialog>

  <dialog id=help>
    <h2>Perf Help</h2>
    <table>
      <tr><td colspan=2><h3>Mouse Controls</h3></td></tr>
      <tr><td class=mono>Hover</td><td>Snap crosshair to closest point.</td></tr>
      <tr><td class=mono>Shift + Hover</td><td>Highlight closest trace.</td></tr>
      <tr><td class=mono>Click</td><td>Select closest point.</td></tr>
      <tr><td colspan=2><h3>Keyboard Controls</h3></td></tr>
      <tr><td class=mono>'w'/'s'</td><td>Zoom in/out.<sup>1</sup></td></tr>
      <tr><td class=mono>'a'/'d'</td><td>Pan left/right.<sup>1</sup></td></tr>
      <tr><td class=mono>'?'</td><td>Show help.</td></tr>
      <tr><td class=mono>Esc</td><td>Stop showing help.</td></tr>
    </table>
    <div class=footnote>
      <sup>1</sup> And Dvorak equivalents.
    </div>
  </dialog>

    <div id=tabs ?hide_if_no_data=${!ele._hasData()}>
      <tabs-sk id=detailTab>
        <button>Params</button>
        <button id=commitsTab disabled>Details</button>
      </tabs-sk>
      <tabs-panel-sk>
        <div>
          <p>
            <b>Trace ID</b>: <span title='Trace ID' id=trace_id></span>
          </p>
          <paramset-sk id=paramset clickable_values @paramset-key-value-click=${ele._paramsetKeyValueClick}></paramset-sk>
        </div>
        <div id=details>
          <paramset-sk id=simple_paramset clickable_values @paramset-key-value-click=${ele._paramsetKeyValueClick}></paramset-sk>
          <div>
            <commit-detail-panel-sk id=commits selectable></commit-detail-panel-sk>
            <json-source-sk id=jsonsource></json-source-sk>
          </div>
        </div>
      </tabs-panel-sk>
    </div>
  `;

define('explore-sk', class extends ElementSk {
  constructor() {
    super(template);

    // The data being displayed. This is a serialized dataframe.DataFrame.
    this._dataframe = {
      traceset: {},
    };

    // The state that goes into the URL.
    this.state = {
      begin: Math.floor(Date.now() / 1000 - DEFAULT_RANGE_S),
      end: Math.floor(Date.now() / 1000),
      formulas: [],
      queries: [],
      keys: '', // The id of the shortcut to a list of trace keys.
      xbaroffset: -1, // The offset of the commit in the repo.
      show_zero: true,
      auto_refresh: false,
      num_commits: 50,
      request_type: 1, // TODO(jcgregorio) Use constants in domain-picker-sk.
    };

    // Are we waiting on data from the server.
    this._spinning = false;

    // The id of the current frame request. Will be the empty string if there
    // is no pending request.
    this._requestId = '';

    this._numShift = window.sk.perf.num_shift;

    // The id of the interval timer if we are refreshing.
    this._refreshId = -1;

    // All the data converted into a CVS blob to download.
    this._csvBlob = null;

    // Either null if the user hasn't zoomed, or {xBegin: Date(), xEnd: Date()}.
    this._zoomRange = null;

    // Call this anytime something in this.state is changed. Will be replaced
    // with the real function once stateReflector has been setup.
    this._stateHasChanged = () => { };
  }

  connectedCallback() {
    super.connectedCallback();
    if (this._initialized) {
      return;
    }
    this._initialized = true;
    this._render();

    this._commits = this.querySelector('#commits');
    this._commitsTab = this.querySelector('#commitsTab');
    this._detailTab = this.querySelector('#detailTab');
    this._formula = this.querySelector('#formula');
    this._jsonsource = this.querySelector('#jsonsource');
    this._paramset = this.querySelector('#paramset');
    this._percent = this.querySelector('#percent');
    this._plot = this.querySelector('#plot');
    this._query = this.querySelector('#query');
    this._query_count = this.querySelector('query-count-sk');
    this._range = this.querySelector('#range');
    this._simple_paramset = this.querySelector('#simple_paramset');
    this._spinner = this.querySelector('#spinner');
    this._summary = this.querySelector('#summary');
    this._trace_id = this.querySelector('#trace_id');
    this._csv_download = this.querySelector('#csv_download');
    this._queryDialog = this.querySelector('#query-dialog');
    dialogPolyfill.registerDialog(this._queryDialog);
    this._helpDialog = this.querySelector('#help');
    dialogPolyfill.registerDialog(this._helpDialog);

    // Populate the query element.
    const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
    fetch(`/_/initpage/?tz=${tz}`, {
      method: 'GET',
    }).then(jsonOrThrow).then((json) => {
      const now = Math.floor(Date.now() / 1000);
      this.state.begin = now - 60 * 60 * 24;
      this.state.end = now;
      this._range.state = this.state;

      this._query.key_order = window.sk.perf.key_order;
      this._query.paramset = json.dataframe.paramset;

      // Remove the paramset so it doesn't get displayed in the Params tab.
      json.dataframe.paramset = {};

      // From this point on reflect the state to the URL.
      this._startStateReflector();
    }).catch(errorMessage);

    document.addEventListener('keydown', (e) => this._keyDown(e));
  }

  _keyDown(e) {
    // Ignore IME composition events.
    if (e.isComposing || e.keyCode === 229) {
      return;
    }
    switch (e.key) {
      case '?':
        this._helpDialog.showModal();
        break;
      case ',': // dvorak
      case 'w':
        this._zoomInKey();
        break;
      case 'o': // dvorak
      case 's':
        this._zoomOutKey();
        break;
      case 'a':
        this._zoomLeftKey();
        break;
      case 'e': // dvorak
      case 'd':
        this._zoomRightKey();
        break;
      default:
        break;
    }
  }

  /**
   * @returns {Object} The current zoom and the length between the left and right edges of
   * the zoom as an object of the form:
   *
   *   {
   *     zoom: [2.0, 12.0],
   *     delta: 10.0,
   *   }
   */
  _getCurrentZoom() {
    let zoom = this._plot.zoom;
    if (zoom === null) {
      zoom = [0, this._dataframe.header.length - 1];
    }
    let delta = zoom[1] - zoom[0];
    if (delta < MIN_ZOOM_RANGE) {
      const mid = (zoom[0] + zoom[1]) / 2;
      zoom[0] = mid - MIN_ZOOM_RANGE / 2;
      zoom[1] = mid + MIN_ZOOM_RANGE / 2;
      delta = MIN_ZOOM_RANGE;
    }
    return {
      zoom: zoom,
      delta: delta,
    };
  }

  /**
   * Clamp a single zoom endpoint.
   *
   * @param {Number} z - One end of a zoom range.
   * @returns {Number} The value of z clamped to valid values.
   */
  _clampZoomEnd(z) {
    if (z < 0) {
      z = 0;
    }
    if (z > this._dataframe.header.length - 1) {
      z = this._dataframe.header.length - 1;
    }
    return z;
  }

  /**
   * Fixes up the zoom range so it always make sense.
   *
   * @param {Array<Number>} zoom - The zoom range.
   * @returns {Array<Number>} The zoom range.
   */
  _rationalizeZoom(zoom) {
    zoom[0] = this._clampZoomEnd(zoom[0]);
    zoom[1] = this._clampZoomEnd(zoom[1]);
    if (zoom[0] > zoom[1]) {
      const left = zoom[0];
      zoom[0] = zoom[1];
      zoom[1] = left;
    }
    return zoom;
  }

  _zoomInKey() {
    const cz = this._getCurrentZoom();
    const zoom = [
      cz.zoom[0] + ZOOM_JUMP_PERCENT * cz.delta,
      cz.zoom[1] - ZOOM_JUMP_PERCENT * cz.delta,
    ];
    this._plot.zoom = this._rationalizeZoom(zoom);
  }

  _zoomOutKey() {
    const cz = this._getCurrentZoom();
    const zoom = [
      cz.zoom[0] - ZOOM_JUMP_PERCENT * cz.delta,
      cz.zoom[1] + ZOOM_JUMP_PERCENT * cz.delta,
    ];
    this._plot.zoom = this._rationalizeZoom(zoom);
  }

  _zoomLeftKey() {
    const cz = this._getCurrentZoom();
    const zoom = [
      cz.zoom[0] - ZOOM_JUMP_PERCENT * cz.delta,
      cz.zoom[1] - ZOOM_JUMP_PERCENT * cz.delta,
    ];
    this._plot.zoom = this._rationalizeZoom(zoom);
  }

  _zoomRightKey() {
    const cz = this._getCurrentZoom();
    const zoom = [
      cz.zoom[0] + ZOOM_JUMP_PERCENT * cz.delta,
      cz.zoom[1] + ZOOM_JUMP_PERCENT * cz.delta,
    ];
    this._plot.zoom = this._rationalizeZoom(zoom);
  }

  // Returns true if we have any traces to be displayed.
  _hasData() {
    return Object.keys(this._dataframe.traceset).length > 0 || this._spinning;
  }

  // Open the query dialog box.
  _openQuery() {
    this._queryDialog.showModal();
  }

  _paramsetChanged(e) {
    this._query.paramset = e.detail;
  }

  _queryChangeDelayedHandler(e) {
    this._query_count.current_query = e.detail.q;
  }

  // Reflect the current query to the query summary.
  _queryChangeHandler(e) {
    const query = e.detail.q;
    this._summary.paramsets = [toParamSet(query)];
    const formula = this._formula.value;
    if (formula === '') {
      this._formula.value = `filter("${query}")`;
    } else if ((formula.match(/"/g) || []).length === 2) {
      // Only update the filter query if there's one string in the formula.
      this._formula.value = formula.replace(/".*"/, `"${query}"`);
    }
  }

  // Reflect the focused trace in the paramset.
  _plotTraceFocused(e) {
    this._paramset.highlight = toObject(e.detail.name);
    this._trace_id.textContent = e.detail.name;
  }

  // User has zoomed in on the graph.
  _plotZoom(e) {
    const shouldRender = this._zoomRange === null;
    this._zoomRange = e.detail;
    if (shouldRender) {
      this._render();
    }
  }

  // Fit the time range to the zoom being displayed.
  // Reload all the queries/formulas on the new time range.
  _zoomToRange() {
    this.state.begin = this._zoomRange.xBegin / 1000;
    this.state.end = this._zoomRange.xEnd / 1000;
    this._zoomRange = null;
    this._rangeChangeImpl();
  }

  // Highlight a trace when it is clicked on.
  _traceSelected(e) {
    this._plot.highlight = [e.detail.name];
    this._commits.details = [];

    const x = e.detail.x;
    // loop backwards from x until you get the next
    // non MISSING_DATA_SENTINEL point.
    const commits = [this._dataframe.header[x]];
    const trace = this._dataframe.traceset[e.detail.name];
    for (let i = x - 1; i >= 0; i--) {
      if (trace[i] !== MISSING_DATA_SENTINEL) {
        break;
      }
      commits.push(this._dataframe.header[i]);
    }
    // Convert the trace id into a paramset to display.
    const params = toObject(e.detail.name);
    const paramset = {};
    Object.keys(params).forEach((key) => {
      paramset[key] = [params[key]];
    });

    // Request populated commits from the server.
    fetch('/_/cid/', {
      method: 'POST',
      body: JSON.stringify(commits),
      headers: {
        'Content-Type': 'application/json',
      },
    }).then(jsonOrThrow).then((json) => {
      this._commits.details = json;
      this._commitsTab.disabled = false;
      this._simple_paramset.paramsets = [paramset];
      this._detailTab.selected = COMMIT_TAB_INDEX;
      this._jsonsource.cid = commits[0];
      this._jsonsource.traceid = e.detail.name;
    }).catch(errorMessage);
  }

  _startStateReflector() {
    this._stateHasChanged = stateReflector(() => this.state, (state) => {
      state = this._rationalizeTimeRange(state);
      this.state = state;
      this._range.state = this.state;
      this._render();
      // If there is at least one query, the use the last one to repopulate the
      // query-sk dialog.
      const numQueries = this.state.queries.length;
      if (numQueries >= 1) {
        this._query.current_query = this.state.queries[numQueries - 1];
        this._summary.paramsets = [toParamSet(this.state.queries[numQueries - 1])];
      }
      this._zeroChanged();
      this._autoRefreshChanged();
      this._rangeChangeImpl();
    });
  }

  /**
   * Fixes up the time ranges in the state that came from query values.
   *
   * It is possible for the query URL to specify just the begin or end time,
   * which may end up giving us an inverted time range, i.e. end < begin.
   */
  _rationalizeTimeRange(state) {
    if (state.end <= state.begin) {
      // If dense then just make sure begin is before end.
      if (state.request_type === 1) {
        state.begin = state.end - DEFAULT_RANGE_S;
      } else if (this.state.begin !== state.begin) {
        state.end = state.begin + DEFAULT_RANGE_S;
      } else { // They set 'end' in the URL.
        state.begin = state.end - DEFAULT_RANGE_S;
      }
    }
    return state;
  }

  _paramsetKeyValueClick(e) {
    const keys = [];
    Object.keys(this._dataframe.traceset).forEach((key) => {
      if (_matches(key, e.detail.key, e.detail.value)) {
        keys.push(key);
      }
    });
    // Additively highlight if the ctrl key is pressed.
    if (e.detail.ctrl) {
      this._plot.highlight = this._plot.highlight.concat(keys);
    } else {
      this._plot.highlight = keys;
    }
  }

  _shiftBoth() {
    this._shiftImpl(-this._numShift, this._numShift);
  }

  _shiftRight() {
    this._shiftImpl(this._numShift, this._numShift);
  }

  _shiftLeft() {
    this._shiftImpl(-this._numShift, -this._numShift);
  }

  // Change the current range by the following +/- offsets.
  _shiftImpl(beginOffset, endOffset) {
    const body = {
      begin: this.state.begin,
      begin_offset: beginOffset,
      end: this.state.end,
      end_offset: endOffset,
      num_commits: this.state.num_commits,
      request_type: this.state.request_type,
    };
    fetch('/_/shift/', {
      method: 'POST',
      body: JSON.stringify(body),
      headers: {
        'Content-Type': 'application/json',
      },
    }).then(jsonOrThrow).then((json) => {
      this.state.begin = json.begin;
      this.state.end = json.end;
      this.state.num_commits = json.num_commits;
      this._rangeChangeImpl();
    }).catch(errorMessage);
  }

  // Create a FrameRequest that will re-create the current state of the page.
  _requestFrameBodyFullFromState() {
    return {
      begin: this.state.begin,
      end: this.state.end,
      num_commits: this.state.num_commits,
      request_type: this.state.request_type,
      formulas: this.state.formulas,
      queries: this.state.queries,
      keys: this.state.keys,
    };
  }

  // Reload all the queries/formulas on the given time range.
  _rangeChangeImpl() {
    if (!this.state) {
      return;
    }
    if (this.state.formulas.length === 0 && this.state.queries.length === 0 && this.state.keys === '') {
      return;
    }

    if (this._trace_id) {
      this._trace_id.textContent = '';
    }
    const body = this._requestFrameBodyFullFromState();
    const switchToTab = body.formulas.length > 0 || body.queries.length > 0 || body.keys !== '';
    this._requestFrame(body, (json) => {
      if (json == null) {
        errorMessage('Failed to find any matching traces.');
        return;
      }
      this._plot.removeAll();
      this._addTraces(json, switchToTab);
      this._render();
    });
  }

  _zeroChangeHandler(e) {
    this.state.show_zero = e.target.checked;
    this._stateHasChanged();
    this._zeroChanged();
  }

  _zeroChanged() {
    if (!this._dataframe.header) {
      return;
    }
    if (this.state.show_zero) {
      const lines = {};
      lines[ZERO_NAME] = Array(this._dataframe.header.length).fill(0);
      this._plot.addLines(lines);
    } else {
      this._plot.deleteLines([ZERO_NAME]);
    }
  }

  _autoRefreshHandler(e) {
    this.state.auto_refresh = e.target.checked;
    this._stateHasChanged();
    this._autoRefreshChanged();
  }

  _autoRefreshChanged() {
    if (!this.state.auto_refresh) {
      if (this._refreshId !== -1) {
        clearInterval(this._refreshId);
      }
    } else {
      this._refreshId = setInterval(() => this._autoRefresh(), REFRESH_TIMEOUT);
    }
  }

  _autoRefresh() {
    // Update end to be now.
    this.state.end = Math.floor(Date.now() / 1000);
    const body = this._requestFrameBodyFullFromState();
    const switchToTab = body.formulas.length > 0 || body.queries.length > 0 || body.keys !== '';
    this._requestFrame(body, (json) => {
      this._plot.removeAll();
      this._addTraces(json, switchToTab);
    });
  }

  /**
   * Add traces to the display. Always called from within the
   * this._requestFrame() callback.
   *
   * @param {Object} json - The parsed JSON returned from the server.
   * otherwise replace them all with the new ones.
   * @param {Boolean} tab - If true then switch to the Params tab.
   */
  _addTraces(json, tab) {
    const dataframe = json.dataframe;
    if (dataframe.traceset === null) {
      return;
    }

    // Add in the 0-trace.
    if (this.state.show_zero) {
      dataframe.traceset[ZERO_NAME] = Array(dataframe.header.length).fill(0);
    }

    this._dataframe = dataframe;
    this._plot.removeAll();
    const labels = [];
    dataframe.header.forEach((header) => {
      labels.push(new Date(header.timestamp * 1000));
    });

    this._plot.addLines(dataframe.traceset, labels);

    this._plot.bands = json.skps;

    // Populate the xbar if present.
    if (this.state.xbaroffset !== -1) {
      const xbaroffset = this.state.xbaroffset;
      let xbar = -1;
      this._dataframe.header.forEach((h, i) => {
        if (h.offset === xbaroffset) {
          xbar = i;
        }
      });
      if (xbar !== -1) {
        this._plot.xbar = xbar;
      } else {
        this._plot.xbar = -1;
      }
    } else {
      this._plot.xbar = -1;
    }

    // Populate the paramset element.
    this._paramset.paramsets = [dataframe.paramset];
    if (tab) {
      this._detailTab.selected = PARAMS_TAB_INDEX;
    }
  }

  /**
   * Plot the traces that match this._query.current_query.
   *
   * @param {Boolean} replace - If true then replace all the traces with ones
   * that match this query, otherwise add them to the current traces being
   * displayed.
   */
  _add(replace) {
    this._queryDialog.close();
    const q = this._query.current_query;
    if (!q || q.trim() === '') {
      errorMessage('The query must not be empty.');
      return;
    }
    this.state = Object.assign({}, this.state, this._range.state);
    if (replace) {
      this._removeAll(true);
    }
    if (this.state.queries.indexOf(q) === -1) {
      this.state.queries.push(q);
    }
    const body = this._requestFrameBodyFullFromState();
    this._requestFrame(body, (json) => {
      this._addTraces(json, true);
    });
  }

  /**
   * Removes all traces.
   *
   * @param skipHistory {Boolean} - If true then don't update the URL. Used
   * in calls like _normalize() where this is just an intermediate state we
   * don't want in history.
   */
  _removeAll(skipHistory) {
    this.state.formulas = [];
    this.state.queries = [];
    this.state.keys = '';
    this._plot.removeAll();
    this._dataframe.traceset = {};
    this._paramset.paramsets = [];
    this._trace_id.textContent = '';
    this._zoomRange = null;
    this._detailTab.selected = PARAMS_TAB_INDEX;
    this._render();
    if (!skipHistory) {
      this._stateHasChanged();
    }
  }

  // When Remove Highlighted or Highlighted Only are pressed then create a
  // shortcut for just the traces that are displayed.
  //
  // Note that removing a trace doesn't work if the trace came from a
  // formula that returns multiple traces. This is a known issue that
  // isn't currently worth solving.
  //
  // Returns the Promise that's creating the shortcut, or undefined if
  // there isn't a shortcut to create.
  _reShortCut(keys) {
    if (keys.length === 0) {
      this.state.keys = '';
      this.state.queries = [];
      return undefined;
    }
    const state = {
      keys: keys,
    };
    return fetch('/_/keys/', {
      method: 'POST',
      body: JSON.stringify(state),
      headers: {
        'Content-Type': 'application/json',
      },
    }).then(jsonOrThrow).then((json) => {
      this.state.keys = json.id;
      this.state.queries = [];
      this._stateHasChanged();
    }).catch(errorMessage);
  }

  // Create a shortcut for all of the traces currently being displayed.
  //
  // Returns the Promise that's creating the shortcut, or undefined if
  // there isn't a shortcut to create.
  _shortcutAll() {
    const toShortcut = [];

    Object.keys(this._dataframe.traceset).forEach((key) => {
      if (key[0] === ',') {
        toShortcut.push(key);
      }
    });

    return this._reShortCut(toShortcut);
  }

  // Apply norm() to all the traces currently being displayed.
  _normalize() {
    const promise = this._shortcutAll();
    if (!promise) {
      errorMessage('No traces to normalize.');
      return;
    }
    promise.then(() => {
      const f = `norm(shortcut("${this.state.keys}"))`;
      this._removeAll(true);
      const body = this._requestFrameBodyFullFromState();
      Object.assign(body, {
        formulas: [f],
      });
      this.state.formulas.push(f);
      this._stateHasChanged();
      this._requestFrame(body, (json) => {
        this._addTraces(json, false);
      });
    });
  }

  // Apply scale_by_avg() to all the traces currently being displayed.
  _scale_by_avg() {
    const promise = this._shortcutAll();
    if (!promise) {
      errorMessage('No traces to scale.');
      return;
    }
    promise.then(() => {
      const f = `scale_by_avg(shortcut("${this.state.keys}"))`;
      this._removeAll(true);
      const body = this._requestFrameBodyFullFromState();
      Object.assign(body, {
        formulas: [f],
      });
      this.state.formulas.push(f);
      this._stateHasChanged();
      this._requestFrame(body, (json) => {
        this._addTraces(json, false);
      });
    });
  }

  _removeHighlighted() {
    const ids = this._plot.highlight;
    const toShortcut = [];

    Object.keys(this._dataframe.traceset).forEach((key) => {
      if (ids.indexOf(key) !== -1) {
        // Detect if it is a formula being removed.
        if (this.state.formulas.indexOf(key) !== -1) {
          this.state.formulas.splice(this.state.formulas.indexOf(key), 1);
        }
        return;
      }
      if (key[0] === ',') {
        toShortcut.push(key);
      }
    });

    // Remove the traces from the traceset so they don't reappear.
    ids.forEach((key) => {
      if (this._dataframe.traceset[key] !== undefined) {
        delete this._dataframe.traceset[key];
      }
    });
    this._plot.deleteLines(ids);
    this._reShortCut(toShortcut);
  }

  _highlightedOnly() {
    const ids = this._plot.highlight;
    const toremove = [];
    const toShortcut = [];

    Object.keys(this._dataframe.traceset).forEach((key) => {
      if (ids.indexOf(key) === -1 && !key.startsWith('special')) {
        // Detect if it is a formula being removed.
        if (this.state.formulas.indexOf(key) !== -1) {
          this.state.formulas.splice(this.state.formulas.indexOf(key), 1);
        } else {
          toremove.push(key);
        }
        return;
      }
      if (key[0] === ',') {
        toShortcut.push(key);
      }
    });

    // Remove the traces from the traceset so they don't reappear.
    toremove.forEach((key) => {
      delete this._dataframe.traceset[key];
    });

    this._plot.deleteLines(toremove);
    this._reShortCut(toShortcut);
  }

  /**
   * Plot the traces from the formula in this._formula.value;
   *
   * @param {Boolean} replace - If true then replace all the traces with the
   * calculated traces from this formula, otherwise add the calculated traces to
   * the current traces being displayed.
   */
  _addCalculated(replace) {
    this._queryDialog.close();
    const f = this._formula.value;
    if (f.trim() === '') {
      errorMessage('The formula must not be empty.');
      return;
    }
    this.state = Object.assign({}, this.state, this._range.state);
    if (replace) {
      this._removeAll(true);
    }
    if (this.state.formulas.indexOf(f) === -1) {
      this.state.formulas.push(f);
    }
    const body = this._requestFrameBodyFullFromState();
    this._requestFrame(body, (json) => {
      this._addTraces(json, false);
    });
  }

  // Common catch function for _requestFrame and _checkFrameRequestStatus.
  _catch(msg) {
    this._requestId = '';
    if (msg) {
      errorMessage(msg, 10000);
    }
    this._percent.textContent = '';
    this.spinning = false;
  }

  /** @prop {Boolean} spinning - True if we are waiting to retrieve data from
   * the server.
   */
  set spinning(b) {
    this._spinning = b;
    this._render();
  }

  get spinning() {
    return this._spinning;
  }

  // Requests a new dataframe, where body is a serialized FrameRequest:
  //
  // {
  //    begin:    1448325780,
  //    end:      1476706336,
  //    formulas: ["ave(filter("name=desk_nytimes.skp&sub_result=min_ms"))"],
  //    hidden:   [],
  //    queries:  [
  //        "name=AndroidCodec_01_original.jpg_SampleSize8",
  //        "name=AndroidCodec_1.bmp_SampleSize8"],
  //    tz:       "America/New_York"
  // };
  //
  // The 'cb' callback function will be called with the decoded JSON body
  // of the response once it's available.
  _requestFrame(body, cb) {
    body.tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
    if (this._requestId !== '') {
      errorMessage('There is a pending query already running.');
      return;
    }
    this._requestId = 'About to make request';

    this.spinning = true;

    this._stateHasChanged();
    fetch('/_/frame/start', {
      method: 'POST',
      body: JSON.stringify(body),
      headers: {
        'Content-Type': 'application/json',
      },
    }).then(jsonOrThrow).then((json) => {
      this._requestId = json.id;
      this._checkFrameRequestStatus(cb);
    }).catch((msg) => this._catch(msg));
  }

  // Periodically check the status of a pending FrameRequest, calling the
  // 'cb' callback with the decoded JSON upon success.
  _checkFrameRequestStatus(cb) {
    fetch(`/_/frame/status/${this._requestId}`, {
      method: 'GET',
    }).then(jsonOrThrow).then((json) => {
      if (json.state === 'Running') {
        this._percent.textContent = `${Math.floor(json.percent * 100)}%`;
        window.setTimeout(() => this._checkFrameRequestStatus(cb), 300);
      } else {
        fetch(`/_/frame/results/${this._requestId}`, {
          method: 'GET',
        }).then(jsonOrThrow).then((json) => {
          cb(json);
          this._catch(json.msg);
        }).catch((msg) => this._catch(msg));
      }
    }).catch((msg) => this._catch(msg));
  }

  // Download all the displayed data as a CSV file.
  _csv() {
    if (this._csvBlob) {
      URL.revokeObjectURL(this._csvBlob);
      this._csvBlob = null;
    }
    const csv = [];
    let line = ['id'];
    this._dataframe.header.forEach((_, i) => {
      // TODO(jcgregorio) Look up the git hash and use that as the header.
      line.push(i);
    });
    csv.push(line.join(','));
    Object.keys(this._dataframe.traceset).forEach((traceId) => {
      if (traceId === ZERO_NAME) {
        return;
      }
      line = [`"${traceId}"`];
      this._dataframe.traceset[traceId].forEach((f) => {
        if (f !== MISSING_DATA_SENTINEL) {
          line.push(f);
        } else {
          line.push('');
        }
      });
      csv.push(line.join(','));
    });
    this._csvBlob = new Blob([csv.join('\n')], { type: 'text/csv' });
    this._csv_download.href = URL.createObjectURL(this._csvBlob);
    this._csv_download.click();
  }

  _isZero(n) {
    return n === 0;
  }
});
