<!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="/experimental/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);
      });
    }

    for (var event of model.descendentEvents()) {
      if (!(event instanceof tr.model.ThreadSlice))
        continue;
      if (filterFunction && !filterFunction(event))
        continue;

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

      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;
  }

  tr.mre.FunctionRegistry.register(getSliceCostReport);

  return {
    SliceCostInfo: SliceCostInfo,

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