// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var WaterfallRow = (function() {
  'use strict';

  /**
   * A WaterfallRow represents the row corresponding to a single SourceEntry
   * displayed by the EventsWaterfallView.
   *
   * @constructor
   */

  // TODO(viona):
  // -Support nested events.
  // -Handle updating length when an event is stalled.
  function WaterfallRow(parentView, sourceEntry) {
    this.parentView_ = parentView;
    this.sourceEntry_ = sourceEntry;

    this.description_ = sourceEntry.getDescription();

    this.createRow_();
  }

  // Offset of popup from mouse location.
  var POPUP_OFFSET_FROM_CURSOR = 25;

  WaterfallRow.prototype = {
    onSourceUpdated: function() {
      this.updateRow();
    },

    updateRow: function() {
      var scale = this.parentView_.getScaleFactor();
      // In some cases, the REQUEST_ALIVE event has been received, while the
      // URL Request to start the job has not been received. In that case, the
      // description obtained is incorrect. The following fixes that.
      if (this.description_ == '') {
        this.sourceCell_.innerHTML = '';
        this.description_ = this.sourceEntry_.getDescription();
        addTextNode(this.sourceCell_, this.description_);
      }

      this.rowCell_.innerHTML = '';

      var matchingEventPairs =
          WaterfallRow.findUrlRequestEvents(this.sourceEntry_);

      // Creates the spacing in the beginning to show start time.
      var startTime = this.parentView_.getStartTime();
      var sourceEntryStartTime = this.getStartTime();
      var delay = sourceEntryStartTime - startTime;
      var frontNode = addNode(this.rowCell_, 'div');
      frontNode.classList.add('waterfall-view-padding');
      setNodeWidth(frontNode, delay * scale);

      var barCell = addNode(this.rowCell_, 'div');
      barCell.classList.add('waterfall-view-bar');

      if (this.sourceEntry_.isError()) {
        barCell.classList.add('error');
      }

      var currentEnd = sourceEntryStartTime;

      for (var i = 0; i < matchingEventPairs.length; ++i) {
        var event = matchingEventPairs[i];
        var startTicks = event.startEntry.time;
        var endTicks = event.endEntry.time;
        event.eventType = event.startEntry.type;
        event.startTime = timeutil.convertTimeTicksToTime(startTicks);
        event.endTime = timeutil.convertTimeTicksToTime(endTicks);
        event.eventDuration = event.endTime - event.startTime;

        // Handles the spaces between events.
        if (currentEnd < event.startTime) {
          var eventDuration = event.startTime - currentEnd;
          var padNode = this.createNode_(
              barCell, eventDuration, this.sourceTypeString_, 'source');
        }

        // Creates event bars.
        var eventNode = this.createNode_(
            barCell, event.eventDuration, EventTypeNames[event.eventType],
            event);
        currentEnd = event.startTime + event.eventDuration;
      }

      // Creates a bar for the part after the last event.
      if (this.getEndTime() > currentEnd) {
        var endDuration = (this.getEndTime() - currentEnd);
        var endNode = this.createNode_(
            barCell, endDuration, this.sourceTypeString_, 'source');
      }
    },

    getStartTime: function() {
      return this.sourceEntry_.getStartTime();
    },

    getEndTime: function() {
      return this.sourceEntry_.getEndTime();
    },

    clearPopup_: function(parentNode) {
      parentNode.innerHTML = '';
    },

    createPopup_: function(parentNode, event, eventType, duration, mouse) {
      var tableStart = this.parentView_.getStartTime();

      var newPopup = addNode(parentNode, 'div');
      newPopup.classList.add('waterfall-view-popup');

      var popupList = addNode(newPopup, 'ul');
      popupList.classList.add('waterfall-view-popup-list');

      popupList.style.maxWidth =
          $(WaterfallView.MAIN_BOX_ID).offsetWidth * 0.5 + 'px';

      this.createPopupItem_(
          popupList, 'Has Error', this.sourceEntry_.isError());

      this.createPopupItem_(
          popupList, 'Event Type', eventType);

      if (event != 'source') {
        this.createPopupItem_(
          popupList, 'Event Duration', duration.toFixed(0) + 'ms');
        this.createPopupItem_(
            popupList, 'Event Start Time', event.startTime - tableStart + 'ms');
        this.createPopupItem_(
            popupList, 'Event End Time', event.endTime - tableStart + 'ms');
      }
      this.createPopupItem_(
            popupList, 'Source Duration',
            this.getEndTime() - this.getStartTime() + 'ms');
      this.createPopupItem_(
          popupList, 'Source Start Time',
          this.getStartTime() - tableStart + 'ms');
      this.createPopupItem_(
          popupList, 'Source End Time', this.getEndTime() - tableStart + 'ms');
      this.createPopupItem_(
          popupList, 'Source ID', this.sourceEntry_.getSourceId());
      var urlListItem = this.createPopupItem_(
          popupList, 'Source Description', this.description_);

      urlListItem.classList.add('waterfall-view-popup-list-url-item');

      // Fixes cases where the popup appears 'off-screen'.
      var popupLeft = mouse.pageX - newPopup.offsetWidth;
      if (popupLeft < 0) {
        popupLeft = mouse.pageX;
      }
      newPopup.style.left = popupLeft +
          $(WaterfallView.MAIN_BOX_ID).scrollLeft -
          $(WaterfallView.BAR_TABLE_ID).offsetLeft + 'px';

      var popupTop = mouse.pageY - newPopup.offsetHeight -
          POPUP_OFFSET_FROM_CURSOR;
      if (popupTop < 0) {
        popupTop = mouse.pageY;
      }
      newPopup.style.top = popupTop +
          $(WaterfallView.MAIN_BOX_ID).scrollTop -
          $(WaterfallView.BAR_TABLE_ID).offsetTop + 'px';
    },

    createPopupItem_: function(parentPopup, key, popupInformation) {
      var popupItem = addNode(parentPopup, 'li');
      addTextNode(popupItem, key + ': ' + popupInformation);
      return popupItem;
    },

    createRow_: function() {
      // Create a row.
      var tr = addNode($(WaterfallView.BAR_TBODY_ID), 'tr');
      tr.classList.add('waterfall-view-table-row');

      // Creates the color bar.

      var rowCell = addNode(tr, 'td');
      rowCell.classList.add('waterfall-view-row');
      this.rowCell_ = rowCell;

      this.sourceTypeString_ = this.sourceEntry_.getSourceTypeString();

      var infoTr = addNode($(WaterfallView.INFO_TBODY_ID), 'tr');
      infoTr.classList.add('waterfall-view-information-row');

      var idCell = addNode(infoTr, 'td');
      idCell.classList.add('waterfall-view-id-cell');
      var idValue = this.sourceEntry_.getSourceId();
      var idLink = addNodeWithText(idCell, 'a', idValue);
      idLink.href = '#events&s=' + idValue;

      var sourceCell = addNode(infoTr, 'td');
      sourceCell.classList.add('waterfall-view-url-cell');
      addTextNode(sourceCell, this.description_);
      this.sourceCell_ = sourceCell;

      this.updateRow();
    },

    // Generates nodes.
    createNode_: function(parentNode, duration, eventTypeString, event) {
      var linkNode = addNode(parentNode, 'a');
      linkNode.href = '#events&s=' + this.sourceEntry_.getSourceId();

      var scale = this.parentView_.getScaleFactor();
      var newNode = addNode(linkNode, 'div');
      setNodeWidth(newNode, duration * scale);
      newNode.classList.add(eventTypeToCssClass_(eventTypeString));
      newNode.classList.add('waterfall-view-bar-component');
      newNode.addEventListener(
          'mouseover',
          this.createPopup_.bind(this, newNode, event, eventTypeString,
              duration),
          true);
      newNode.addEventListener(
          'mouseout', this.clearPopup_.bind(this, newNode), true);
      return newNode;
    },
  };

  /**
   * Identifies source dependencies and extracts events of interest for use in
   * inlining in URL Request bars.
   * Created as static function for testing purposes.
   */
  WaterfallRow.findUrlRequestEvents = function(sourceEntry) {
    var eventPairs = [];
    if (!sourceEntry) {
      return eventPairs;
    }

    // One level down from URL Requests.

    var httpStreamJobSources = findDependenciesOfType_(
        sourceEntry, EventType.HTTP_STREAM_REQUEST_BOUND_TO_JOB);

    var httpTransactionReadHeadersPairs = findEntryPairsFromSourceEntries_(
        [sourceEntry], EventType.HTTP_TRANSACTION_READ_HEADERS);
    eventPairs = eventPairs.concat(httpTransactionReadHeadersPairs);

    var proxyServicePairs = findEntryPairsFromSourceEntries_(
        httpStreamJobSources, EventType.PROXY_SERVICE);
    eventPairs = eventPairs.concat(proxyServicePairs);

    if (httpStreamJobSources.length > 0) {
      for (var i = 0; i < httpStreamJobSources.length; ++i) {
        // Two levels down from URL Requests.

        var hostResolverImplSources = findDependenciesOfType_(
            httpStreamJobSources[i], EventType.HOST_RESOLVER_IMPL);

        var socketSources = findDependenciesOfType_(
            httpStreamJobSources[i], EventType.SOCKET_POOL_BOUND_TO_SOCKET);

        // Three levels down from URL Requests.

        // TODO(mmenke):  Some of these may be nested in the PROXY_SERVICE
        //                event, resulting in incorrect display, since nested
        //                events aren't handled.
        var hostResolverImplRequestPairs = findEntryPairsFromSourceEntries_(
            hostResolverImplSources, EventType.HOST_RESOLVER_IMPL_REQUEST);
        eventPairs = eventPairs.concat(hostResolverImplRequestPairs);

        // Truncate times of connection events such that they don't occur before
        // the HTTP_STREAM_JOB event or the PROXY_SERVICE event.
        // TODO(mmenke):  The last HOST_RESOLVER_IMPL_REQUEST may still be a
        //                problem.
        var minTime = httpStreamJobSources[i].getLogEntries()[0].time;
        if (proxyServicePairs.length > 0)
          minTime = proxyServicePairs[0].endEntry.time;
        // Convert to number so comparisons will be numeric, not string,
        // comparisons.
        minTime = Number(minTime);

        var tcpConnectPairs = findEntryPairsFromSourceEntries_(
            socketSources, EventType.TCP_CONNECT);

        var sslConnectPairs = findEntryPairsFromSourceEntries_(
            socketSources, EventType.SSL_CONNECT);

        var connectionPairs = tcpConnectPairs.concat(sslConnectPairs);

        // Truncates times of connection events such that they are shown after a
        // proxy service event.
        for (var k = 0; k < connectionPairs.length; ++k) {
          var eventPair = connectionPairs[k];
          var eventInRange = false;
          if (eventPair.startEntry.time >= minTime) {
            eventInRange = true;
          } else if (eventPair.endEntry.time > minTime) {
            eventInRange = true;
            // Should not modify original object.
            eventPair.startEntry = shallowCloneObject(eventPair.startEntry);
            // Need to have a string, for consistency.
            eventPair.startEntry.time = minTime + '';
          }
          if (eventInRange) {
            eventPairs.push(eventPair);
          }
        }
      }
    }
    eventPairs.sort(function(a, b) {
      return a.startEntry.time - b.startEntry.time;
    });
    return eventPairs;
  }

  function eventTypeToCssClass_(eventType) {
    return eventType.toLowerCase().replace(/_/g, '-');
  }

  /**
   * Finds all events of input type from the input list of Source Entries.
   * Returns an ordered list of start and end log entries.
   */
  function findEntryPairsFromSourceEntries_(sourceEntryList, eventType) {
    var eventPairs = [];
    for (var i = 0; i < sourceEntryList.length; ++i) {
      var sourceEntry = sourceEntryList[i];
      if (sourceEntry) {
        var entries = sourceEntry.getLogEntries();
        var matchingEventPairs = findEntryPairsByType_(entries, eventType);
        eventPairs = eventPairs.concat(matchingEventPairs);
      }
    }
    return eventPairs;
  }

  /**
   * Finds all events of input type from the input list of log entries.
   * Returns an ordered list of start and end log entries.
   */
  function findEntryPairsByType_(entries, eventType) {
    var matchingEventPairs = [];
    var startEntry = null;
    for (var i = 0; i < entries.length; ++i) {
      var currentEntry = entries[i];
      if (eventType != currentEntry.type) {
        continue;
      }
      if (currentEntry.phase == EventPhase.PHASE_BEGIN) {
        startEntry = currentEntry;
      }
      if (startEntry && currentEntry.phase == EventPhase.PHASE_END) {
        var event = {
          startEntry: startEntry,
          endEntry: currentEntry,
        };
        matchingEventPairs.push(event);
        startEntry = null;
      }
    }
    return matchingEventPairs;
  }

  /**
   * Returns an ordered list of SourceEntries that are dependencies for
   * events of the given type.
   */
  function findDependenciesOfType_(sourceEntry, eventType) {
    var sourceEntryList = [];
    if (sourceEntry) {
      var eventList = findEventsInSourceEntry_(sourceEntry, eventType);
      for (var i = 0; i < eventList.length; ++i) {
        var foundSourceEntry = findSourceEntryFromEvent_(eventList[i]);
        if (foundSourceEntry) {
          sourceEntryList.push(foundSourceEntry);
        }
      }
    }
    return sourceEntryList;
  }

  /**
   * Returns an ordered list of events from the given sourceEntry with the
   * given type.
   */
  function findEventsInSourceEntry_(sourceEntry, eventType) {
    var entries = sourceEntry.getLogEntries();
    var events = [];
    for (var i = 0; i < entries.length; ++i) {
      var currentEntry = entries[i];
      if (currentEntry.type == eventType) {
        events.push(currentEntry);
      }
    }
    return events;
  }

  /**
   * Follows the event to obtain the sourceEntry that is the source
   * dependency.
   */
  function findSourceEntryFromEvent_(event) {
    if (!('params' in event) || !('source_dependency' in event.params)) {
      return undefined;
    } else {
      var id = event.params.source_dependency.id;
      return SourceTracker.getInstance().getSourceEntry(id);
    }
  }

  return WaterfallRow;
})();
