<!DOCTYPE html>
<!--
Copyright (c) 2015 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="/perf_insights/mappers/reduce.html">
<link rel="import" href="/tracing/extras/ads/domain_category.html">
<link rel="import" href="/tracing/extras/chrome/slice_title_fixer.html">
<link rel="import" href="/tracing/model/source_info/js_source_info.html">

<script>
'use strict';

tr.exportTo('pi.m', function() {
  var JSSourceState = tr.model.source_info.JSSourceState;

  function SliceCostInfo() {
    this.threadGroup = undefined;
    this.railTypeName = undefined;
    this.title = undefined;
    this.domainCategory = undefined;
    this.domain = undefined;
    this.userFriendlyCategory = undefined;

    this.selfTime = 0;
    this.cpuSelfTime = 0;

    this.jsTime = 0;
    this.jsTimeByState = {};
    for (var state in JSSourceState) {
      this.jsTimeByState[JSSourceState[state]] = 0;
    }
    this.data = {};
  }

  SliceCostInfo.asReduceTarget = function(key, firstValue) {
    var sliceCostInfo = new SliceCostInfo();
    sliceCostInfo.threadGroup = firstValue.threadGroup;
    sliceCostInfo.railTypeName = firstValue.railTypeName;
    sliceCostInfo.title = firstValue.title;
    sliceCostInfo.domainCategory = firstValue.domainCategory;
    sliceCostInfo.domain = firstValue.domain;
    sliceCostInfo.userFriendlyCategory = firstValue.userFriendlyCategory;
    sliceCostInfo.data = firstValue.data;
    return sliceCostInfo;
  };

  SliceCostInfo.fromDict = function(d) {
    var sliceCostInfo = new SliceCostInfo();
    sliceCostInfo.threadGroup = d.threadGroup;
    sliceCostInfo.railTypeName = d.railTypeName;
    sliceCostInfo.title = d.title;
    sliceCostInfo.domainCategory = d.domainCategory;
    sliceCostInfo.domain = d.domain;
    sliceCostInfo.userFriendlyCategory = d.userFriendlyCategory;
    sliceCostInfo.selfTime = d.selfTime;
    sliceCostInfo.cpuSelfTime = d.cpuSelfTime;
    sliceCostInfo.jsTime = d.jsTime || 0;
    for (var state in JSSourceState) {
      if (d.jsTimeByState === undefined) {
        sliceCostInfo.jsTimeByState[state] = 0;
      } else {
        sliceCostInfo.jsTimeByState[JSSourceState[state]] =
            d.jsTimeByState[JSSourceState[state]] || 0;
      }
    }
    sliceCostInfo.data = d.data;
    return sliceCostInfo;
  };

  SliceCostInfo.prototype = {
    push: function(sliceCostKey, threadSlice) {
      if (threadSlice.selfTime !== undefined)
        this.selfTime += threadSlice.selfTime;
      if (threadSlice.cpuSelfTime !== undefined)
        this.cpuSelfTime += threadSlice.cpuSelfTime;
      if (threadSlice.jsTime !== undefined)
        this.jsTime += threadSlice.jsTime;
      if (threadSlice.jsTimeByState !== undefined) {
        for (var state in JSSourceState) {
          this.jsTimeByState[JSSourceState[state]] +=
              threadSlice.jsTimeByState[JSSourceState[state]];
        }
      }
    },

    finalizeAndGetResult: function() {
      return this;
    }
  };


  function getSliceCostReport(model, threadGrouping, railTypeNameByGUID,
      filterFunction, dataCB) {
    var reduce = new pi.m.StreamingReducer(SliceCostInfo.asReduceTarget);

    function generateDomainCosts(slice) {
      // V8.Execute events may generate several sliceCostInfo, based on the
      // origin of the JS being executed.
      var range = new tr.b.Range();
      slice.addBoundsToRange(range);
      var filtered = range.filterArray(
          slice.parentContainer.samples,
          function(sample) {return sample.start;});
      filtered.forEach(function(sample) {
        var sliceCostInfo = new SliceCostInfo();
        sliceCostInfo.threadGroup = threadGrouping.getGroupNameForEvent(slice);
        sliceCostInfo.railTypeName = railTypeNameByGUID[slice.guid];

        var ufc = model.getUserFriendlyCategoryFromEvent(slice);
        sliceCostInfo.userFriendlyCategory = ufc || 'other';
        sliceCostInfo.title = tr.e.chrome.SliceTitleFixer.fromEvent(slice);
        sliceCostInfo.domain = sample.leafStackFrame.domain;
        sliceCostInfo.domainCategory =
            tr.e.ads.DomainCategory.fromDomain(sliceCostInfo.domain);
        sliceCostInfo.selfTime = sample.weight;
        sliceCostInfo.cpuSelfTime = sample.weight;
        if (dataCB !== undefined)
          sliceCostInfo.data = dataCB(slice);
        // Let's use the state of the leaf frame. TODO(chiniforooshan):
        // understand what it means if frames of a sample stack are in different
        // states (BUG #1542).
        var sourceInfo = sample.leafStackFrame.sourceInfo;
        if (sourceInfo === undefined ||
            !(sourceInfo instanceof tr.model.source_info.JSSourceInfo)) {
          sliceCostInfo.jsTime = sample.weight;
          sliceCostInfo.jsTimeByState[JSSourceState.UNKNOWN] = sample.weight;
        } else {
          sliceCostInfo.jsTimeByState[sourceInfo.state] = sample.weight;
        }
        var key = sliceCostInfo.threadGroup + '/' +
                  sliceCostInfo.railTypeName + '/' +
                  sliceCostInfo.title + '/' +
                  sliceCostInfo.domain;
        reduce.push(key, sliceCostInfo);
      });
    }

    model.iterateAllEvents(function(event) {
      if (!(event instanceof tr.model.ThreadSlice))
        return;
      if (filterFunction && !filterFunction(event))
        return;

      var threadSlice = event;
      if (threadSlice.title === 'V8.Execute') {
        generateDomainCosts(threadSlice);
        return;
      }

      var sliceCostInfo = new SliceCostInfo();
      sliceCostInfo.threadGroup = threadGrouping.getGroupNameForEvent(
          threadSlice);
      sliceCostInfo.railTypeName = railTypeNameByGUID[threadSlice.guid];
      var ufc = model.getUserFriendlyCategoryFromEvent(threadSlice);
      sliceCostInfo.userFriendlyCategory = ufc || 'other';
      sliceCostInfo.title = tr.e.chrome.SliceTitleFixer.fromEvent(threadSlice);
      // For all other events, just generate one sliceCostInfo.
      sliceCostInfo.selfTime = threadSlice.selfTime;
      sliceCostInfo.cpuSelfTime = threadSlice.cpuSelfTime;
      if (dataCB !== undefined)
        sliceCostInfo.data = dataCB(event);

      var key = sliceCostInfo.threadGroup + '/' +
                sliceCostInfo.railTypeName + '/' +
                sliceCostInfo.title;
      reduce.push(key, sliceCostInfo);
    });

    var sliceCostInfos = [];
    reduce.finalizeAndIterResults(function(key, sliceCostInfo) {
      sliceCostInfos.push(sliceCostInfo);
    });
    return sliceCostInfos;
  }

  return {
    SliceCostInfo: SliceCostInfo,

    getSliceCostReport: getSliceCostReport
  };
});
</script>
