<!DOCTYPE html>
<!--
Copyright (c) 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.
-->

<link rel="import" href="/core/trace_model/event_container.html">
<link rel="import" href="/core/filter.html">
<link rel="import" href="/base/ui/color_scheme.html">
<link rel="import" href="/base/guid.html">
<link rel="import" href="/base/sorted_array_utils.html">

<script>
'use strict';

/**
 * @fileoverview Provides the SliceGroup class.
 */
tv.exportTo('tv.c.trace_model', function() {
  var Slice = tv.c.trace_model.Slice;

  function getSliceLo(s) {
    return s.start;
  }

  function getSliceHi(s) {
    return s.end;
  }

  /**
   * A group of Slices, plus code to create them from B/E events, as
   * well as arrange them into subRows.
   *
   * Do not mutate the slices array directly. Modify it only by
   * SliceGroup mutation methods.
   *
   * @constructor
   * @param {function(new:Slice, category, title, colorId, start, args)=}
   *     opt_sliceConstructor The constructor to use when creating slices.
   * @extends {tv.c.trace_model.EventContainer}
   */
  function SliceGroup(parentThread, opt_sliceConstructor, opt_name) {
    this.guid_ = tv.b.GUID.allocate();

    this.parentThread_ = parentThread;

    var sliceConstructor = opt_sliceConstructor || Slice;
    this.sliceConstructor = sliceConstructor;

    this.openPartialSlices_ = [];

    this.slices = [];
    this.bounds = new tv.b.Range();
    this.topLevelSlices = [];
    this.haveTopLevelSlicesBeenBuilt = false;
    this.name_ = opt_name;
  }

  SliceGroup.prototype = {
    __proto__: tv.c.trace_model.EventContainer.prototype,

    get guid() {
      return this.guid_;
    },

    get parentThread() {
      return this.parentThread_;
    },

    get model() {
      return this.parentThread_.parent.model;
    },

    get stableId() {
      return this.parentThread_.stableId + '.SliceGroup';
    },

    getSettingsKey: function() {
      if (!this.name_)
        return undefined;
      var parentKey = this.parentThread_.getSettingsKey();
      if (!parentKey)
        return undefined;
      return parentKey + '.' + this.name;
    },

    /**
     * @return {Number} The number of slices in this group.
     */
    get length() {
      return this.slices.length;
    },

    /**
     * Helper function that pushes the provided slice onto the slices array.
     * @param {Slice} slice The slice to be added to the slices array.
     */
    pushSlice: function(slice) {
      this.haveTopLevelSlicesBeenBuilt = false;
      this.slices.push(slice);
      return slice;
    },

    /**
     * Helper function that pushes the provided slices onto the slices array.
     * @param {Array.<Slice>} slices An array of slices to be added.
     */
    pushSlices: function(slices) {
      this.haveTopLevelSlicesBeenBuilt = false;
      this.slices.push.apply(this.slices, slices);
    },

    /**
     * Opens a new slice in the group's slices.
     *
     * Calls to beginSlice and
     * endSlice must be made with non-monotonically-decreasing timestamps.
     *
     * @param {String} category Category name of the slice to add.
     * @param {String} title Title of the slice to add.
     * @param {Number} ts The timetsamp of the slice, in milliseconds.
     * @param {Object.<string, Object>=} opt_args Arguments associated with
     * the slice.
     */
    beginSlice: function(category, title, ts, opt_args, opt_tts) {
      if (this.openPartialSlices_.length) {
        var prevSlice = this.openPartialSlices_[
            this.openPartialSlices_.length - 1];
        if (ts < prevSlice.start)
          throw new Error('Slices must be added in increasing timestamp order');
      }

      var colorId = tv.b.ui.getColorIdForGeneralPurposeString(title);
      var slice = new this.sliceConstructor(category, title, colorId, ts,
                                            opt_args ? opt_args : {}, null,
                                            opt_tts);
      this.openPartialSlices_.push(slice);
      slice.didNotFinish = true;
      this.pushSlice(slice);

      return slice;
    },

    isTimestampValidForBeginOrEnd: function(ts) {
      if (!this.openPartialSlices_.length)
        return true;
      var top = this.openPartialSlices_[this.openPartialSlices_.length - 1];
      return ts >= top.start;
    },

    /**
     * @return {Number} The number of beginSlices for which an endSlice has not
     * been issued.
     */
    get openSliceCount() {
      return this.openPartialSlices_.length;
    },

    get mostRecentlyOpenedPartialSlice() {
      if (!this.openPartialSlices_.length)
        return undefined;
      return this.openPartialSlices_[this.openPartialSlices_.length - 1];
    },

    /**
     * Ends the last begun slice in this group and pushes it onto the slice
     * array.
     *
     * @param {Number} ts Timestamp when the slice ended.
     * @return {Slice} slice.
     */
    endSlice: function(ts, opt_tts) {
      if (!this.openSliceCount)
        throw new Error('endSlice called without an open slice');

      var slice = this.openPartialSlices_[this.openSliceCount - 1];
      this.openPartialSlices_.splice(this.openSliceCount - 1, 1);
      if (ts < slice.start)
        throw new Error('Slice ' + slice.title +
                        ' end time is before its start.');

      slice.duration = ts - slice.start;
      slice.didNotFinish = false;

      if (opt_tts && slice.cpuStart !== undefined)
        slice.cpuDuration = opt_tts - slice.cpuStart;

      return slice;
    },

    /**
     * Push a complete event as a Slice into the slice list.
     * The timestamp can be in any order.
     *
     * @param {String} category Category name of the slice to add.
     * @param {String} title Title of the slice to add.
     * @param {Number} ts The timetsamp of the slice, in milliseconds.
     * @param {Number} duration The duration of the slice, in milliseconds.
     * @param {Object.<string, Object>=} opt_args Arguments associated with
     * the slice.
     */
    pushCompleteSlice: function(category, title, ts, duration, tts,
                                cpuDuration, opt_args) {
      var colorId = tv.b.ui.getColorIdForGeneralPurposeString(title);
      var slice = new this.sliceConstructor(category, title, colorId, ts,
                                            opt_args ? opt_args : {},
                                            duration, tts, cpuDuration);
      if (duration === undefined)
        slice.didNotFinish = true;
      this.pushSlice(slice);
      return slice;
    },

    /**
     * Closes any open slices.
     * @param {Number=} opt_maxTimestamp The end time to use for the closed
     * slices. If not provided,
     * the max timestamp for this slice is provided.
     */
    autoCloseOpenSlices: function(opt_maxTimestamp) {
      if (!opt_maxTimestamp) {
        this.updateBounds();
        opt_maxTimestamp = this.bounds.max;
      }
      for (var sI = 0; sI < this.slices.length; sI++) {
        var slice = this.slices[sI];
        if (slice.didNotFinish)
          slice.duration = opt_maxTimestamp - slice.start;
      }
      this.openPartialSlices_ = [];
    },

    /**
     * Shifts all the timestamps inside this group forward by the amount
     * specified.
     */
    shiftTimestampsForward: function(amount) {
      for (var sI = 0; sI < this.slices.length; sI++) {
        var slice = this.slices[sI];
        slice.start = (slice.start + amount);
      }
    },

    /**
     * Updates the bounds for this group based on the slices it contains.
     */
    updateBounds: function() {
      this.bounds.reset();
      for (var i = 0; i < this.slices.length; i++) {
        this.bounds.addValue(this.slices[i].start);
        this.bounds.addValue(this.slices[i].end);
      }
    },

    copySlice: function(slice) {
      var newSlice = new this.sliceConstructor(slice.category, slice.title,
          slice.colorId, slice.start,
          slice.args, slice.duration, slice.cpuStart, slice.cpuDuration);
      newSlice.didNotFinish = slice.didNotFinish;
      return newSlice;
    },

    iterateAllEventsInThisContainer: function(eventTypePredicate,
                                              callback, opt_this) {
      if (eventTypePredicate.call(opt_this, this.sliceConstructor))
        this.slices.forEach(callback, opt_this);
    },

    iterateAllChildEventContainers: function(callback, opt_this) {
    },

    getSlicesOfName: function(title) {
      var slices = [];
      for (var i = 0; i < this.slices.length; i++) {
        if (this.slices[i].title == title) {
          slices.push(this.slices[i]);
        }
      }
      return slices;
    },

    iterSlicesInTimeRange: function(callback, start, end) {
      var ret = [];
      tv.b.iterateOverIntersectingIntervals(
        this.topLevelSlices,
        function(s) { return s.start; },
        function(s) { return s.duration; },
        start,
        end,
        function(topLevelSlice) {
          callback(topLevelSlice);
          topLevelSlice.iterateAllDescendents(callback);
        });
      return ret;
    },

    findSliceAtTs: function(ts) {
      if (!this.haveTopLevelSlicesBeenBuilt)
        throw new Error('Nope');
      var i = tv.b.findIndexInSortedClosedIntervals(
          this.topLevelSlices,
          getSliceLo, getSliceHi,
          ts);
      if (i == -1 || i == this.topLevelSlices.length)
        return undefined;

      var curSlice = this.topLevelSlices[i];

      // Now recurse on slice looking for subSlice of given ts.
      while (true) {
        var i = tv.b.findIndexInSortedClosedIntervals(
            curSlice.subSlices,
            getSliceLo, getSliceHi,
            ts);
        if (i == -1 || i == curSlice.subSlices.length)
          return curSlice;
        curSlice = curSlice.subSlices[i];
      }
    },

    findNextSliceAfter: function(ts, refGuid) {
      var i = tv.b.findLowIndexInSortedArray(
          this.slices, getSliceLo, ts);
      if (i === this.slices.length)
        return undefined;
      for (; i < this.slices.length; i++) {
        var slice = this.slices[i];
        if (slice.start > ts)
          return slice;
        if (slice.guid <= refGuid)
          continue;
        return slice;
      }
      return undefined;
    },

    /**
     * Construct subSlices for this group.
     * Populate the group topLevelSlices, parent slices get a subSlices[],
     * a selfThreadTime and a selfTime, child slices get a parentSlice
     * reference.
     */
    createSubSlices: function() {
      this.haveTopLevelSlicesBeenBuilt = true;
      this.createSubSlicesImpl_();
      if (this.parentThread.timeSlices)
        this.addCpuTimeToSubslices_(this.parentThread.timeSlices);
      this.slices.forEach(function(slice) {
        var selfTime = slice.duration;
        for (var i = 0; i < slice.subSlices.length; i++)
          selfTime -= slice.subSlices[i].duration;
        slice.selfTime = selfTime;

        if (slice.cpuDuration === undefined)
          return;

        var cpuSelfTime = slice.cpuDuration;
        for (var i = 0; i < slice.subSlices.length; i++) {
          if (slice.subSlices[i].cpuDuration !== undefined)
            cpuSelfTime -= slice.subSlices[i].cpuDuration;
        }
        slice.cpuSelfTime = cpuSelfTime;
      });
    },
    createSubSlicesImpl_: function() {
      function addSliceIfBounds(root, child) {
        // Because we know that the start time of child is >= the start time
        // of all other slices seen so far, we can just check the last slice
        // of each row for bounding.
        if (root.bounds(child)) {
          if (root.subSlices && root.subSlices.length > 0) {
            if (addSliceIfBounds(root.subSlices[root.subSlices.length - 1],
                                 child))
              return true;
          }
          child.parentSlice = root;
          if (root.subSlices === undefined)
            root.subSlices = [];
          root.subSlices.push(child);
          return true;
        }
        return false;
      }

      if (!this.slices.length)
        return;

      var ops = [];
      for (var i = 0; i < this.slices.length; i++) {
        if (this.slices[i].subSlices)
          this.slices[i].subSlices.splice(0,
                                          this.slices[i].subSlices.length);
        ops.push(i);
      }

      var originalSlices = this.slices;
      ops.sort(function(ix, iy) {
        var x = originalSlices[ix];
        var y = originalSlices[iy];
        if (x.start != y.start)
          return x.start - y.start;

        // Elements get inserted into the slices array in order of when the
        // slices start. Because slices must be properly nested, we break
        // start-time ties by assuming that the elements appearing earlier
        // in the slices array (and thus ending earlier) start earlier.
        return ix - iy;
      });

      var slices = new Array(this.slices.length);
      for (var i = 0; i < ops.length; i++) {
        slices[i] = originalSlices[ops[i]];
      }

      // Actually build the subrows.
      var rootSlice = slices[0];
      this.topLevelSlices = [];
      this.topLevelSlices.push(rootSlice);
      for (var i = 1; i < slices.length; i++) {
        var slice = slices[i];
        if (!addSliceIfBounds(rootSlice, slice)) {
          rootSlice = slice;
          this.topLevelSlices.push(rootSlice);
        }
      }

      // Keep the slices in sorted form.
      this.slices = slices;
    },
    addCpuTimeToSubslices_: function(timeSlices) {
      var SCHEDULING_STATE = tv.c.trace_model.SCHEDULING_STATE;
      var sliceIdx = 0;
      timeSlices.forEach(function(timeSlice) {
        if (timeSlice.schedulingState == SCHEDULING_STATE.RUNNING) {
          while (sliceIdx < this.topLevelSlices.length) {
            if (this.addCpuTimeToSubslice_(this.topLevelSlices[sliceIdx],
                timeSlice)) {
              // The current top-level slice and children are fully
              // accounted for, proceed to next top-level slice.
              sliceIdx++;
            } else {
              // The current top-level runs beyond the time slice, break out
              // so we can potentially add more time slices to it
              break;
            }
          }
        }
      }, this);
    },
    /* Add run-time of this timeSlice to the passed in slice
     * and all of it's children (recursively).
     * Returns whether the slice ends before or at the end of the
     * time slice, signaling we are done with this slice.
     */
    addCpuTimeToSubslice_: function(slice, timeSlice) {
      // Make sure they overlap
      if (slice.start > timeSlice.end || slice.end < timeSlice.start)
        return slice.end <= timeSlice.end;

      // Compute actual overlap
      var duration = timeSlice.duration;
      if (slice.start > timeSlice.start)
        duration -= slice.start - timeSlice.start;
      if (timeSlice.end > slice.end)
        duration -= timeSlice.end - slice.end;

      if (slice.cpuDuration) {
        slice.cpuDuration += duration;
      } else {
        slice.cpuDuration = duration;
      }

      for (var i = 0; i < slice.subSlices.length; i++) {
        this.addCpuTimeToSubslice_(slice.subSlices[i], timeSlice);
      }

      return slice.end <= timeSlice.end;
    }
  };

  /**
   * Merge two slice groups.
   *
   * If the two groups do not nest properly some of the slices of groupB will
   * be split to accomodate the improper nesting.  This is done to accomodate
   * combined kernel and userland call stacks on Android.  Because userland
   * tracing is done by writing to the trace_marker file, the kernel calls
   * that get invoked as part of that write may not be properly nested with
   * the userland call trace.  For example the following sequence may occur:
   *
   *     kernel enter sys_write        (the write to trace_marker)
   *     user   enter some_function
   *     kernel exit  sys_write
   *     ...
   *     kernel enter sys_write        (the write to trace_marker)
   *     user   exit  some_function
   *     kernel exit  sys_write
   *
   * This is handled by splitting the sys_write call into two slices as
   * follows:
   *
   *     | sys_write |            some_function            | sys_write (cont.) |
   *                 | sys_write (cont.) |     | sys_write |
   *
   * The colorId of both parts of the split slices are kept the same, and the
   * " (cont.)" suffix is appended to the later parts of a split slice.
   *
   * The two input SliceGroups are not modified by this, and the merged
   * SliceGroup will contain a copy of each of the input groups' slices (those
   * copies may be split).
   */
  SliceGroup.merge = function(groupA, groupB) {
    // This is implemented by traversing the two slice groups in reverse
    // order.  The slices in each group are sorted by ascending end-time, so
    // we must do the traversal from back to front in order to maintain the
    // sorting.
    //
    // We traverse the two groups simultaneously, merging as we go.  At each
    // iteration we choose the group from which to take the next slice based
    // on which group's next slice has the greater end-time.  During this
    // traversal we maintain a stack of currently "open" slices for each input
    // group.  A slice is considered "open" from the time it gets reached in
    // our input group traversal to the time we reach an slice in this
    // traversal with an end-time before the start time of the "open" slice.
    //
    // Each time a slice from groupA is opened or closed (events corresponding
    // to the end-time and start-time of the input slice, respectively) we
    // split all of the currently open slices from groupB.

    if (groupA.openPartialSlices_.length > 0)
      throw new Error('groupA has open partial slices');

    if (groupB.openPartialSlices_.length > 0)
      throw new Error('groupB has open partial slices');

    if (groupA.parentThread != groupB.parentThread)
      throw new Error('Different parent threads. Cannot merge');

    if (groupA.sliceConstructor != groupB.sliceConstructor)
      throw new Error('Different slice constructors. Cannot merge');

    var result = new SliceGroup(groupA.parentThread,
                                groupA.sliceConstructor,
                                groupA.name_);

    var slicesA = groupA.slices;
    var slicesB = groupB.slices;
    var idxA = 0;
    var idxB = 0;
    var openA = [];
    var openB = [];

    var splitOpenSlices = function(when) {
      for (var i = 0; i < openB.length; i++) {
        var oldSlice = openB[i];
        var oldEnd = oldSlice.end;
        if (when < oldSlice.start || oldEnd < when) {
          throw new Error('slice should not be split');
        }

        var newSlice = result.copySlice(oldSlice);
        newSlice.start = when;
        newSlice.duration = oldEnd - when;
        if (newSlice.title.indexOf(' (cont.)') == -1)
          newSlice.title += ' (cont.)';
        oldSlice.duration = when - oldSlice.start;
        openB[i] = newSlice;
        result.pushSlice(newSlice);
      }
    };

    var closeOpenSlices = function(upTo) {
      while (openA.length > 0 || openB.length > 0) {
        var nextA = openA[openA.length - 1];
        var nextB = openB[openB.length - 1];
        var endA = nextA && nextA.end;
        var endB = nextB && nextB.end;

        if ((endA === undefined || endA > upTo) &&
            (endB === undefined || endB > upTo)) {
          return;
        }

        if (endB === undefined || endA < endB) {
          splitOpenSlices(endA);
          openA.pop();
        } else {
          openB.pop();
        }
      }
    };

    while (idxA < slicesA.length || idxB < slicesB.length) {
      var sA = slicesA[idxA];
      var sB = slicesB[idxB];
      var nextSlice, isFromB;

      if (sA === undefined || (sB !== undefined && sA.start > sB.start)) {
        nextSlice = result.copySlice(sB);
        isFromB = true;
        idxB++;
      } else {
        nextSlice = result.copySlice(sA);
        isFromB = false;
        idxA++;
      }

      closeOpenSlices(nextSlice.start);

      result.pushSlice(nextSlice);

      if (isFromB) {
        openB.push(nextSlice);
      } else {
        splitOpenSlices(nextSlice.start);
        openA.push(nextSlice);
      }
    }

    closeOpenSlices();

    return result;
  };

  return {
    SliceGroup: SliceGroup
  };
});
</script>
