<!DOCTYPE html>
<!--
Copyright (c) 2012 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="/tracing/base/iteration_helpers.html">
<link rel="import" href="/tracing/importer/import.html">
<link rel="import" href="/tracing/model/counter.html">
<link rel="import" href="/tracing/model/model.html">
<link rel="import" href="/tracing/model/slice.html">
<link rel="import" href="/tracing/model/slice_group.html">
<link rel="import" href="/tracing/model/stack_frame.html">
<link rel="import" href="/tracing/model/thread_time_slice.html">
<link rel="import" href="/tracing/model/user_model/stub_expectation.html">

<script>
'use strict';

/**
 * @fileoverview Helper functions for use in tracing tests.
 */
tr.exportTo('tr.c', function() {
  var ColorScheme = tr.b.ColorScheme;

  function _getStartAndCpuDurationFromDict(
      options, required, startFieldName, durationFieldName, endFieldName) {

    if (options[startFieldName] === undefined) {
      if (required)
        throw new Error('Too little information.');
      else
        return {start: undefined, duration: undefined};
    }
    if (options[durationFieldName] !== undefined &&
        options[endFieldName] !== undefined) {
      throw new Error('Too much information.');
    }
    if (options[durationFieldName] === undefined &&
        options[endFieldName] === undefined) {
      if (required)
        throw new Error('Too little information.');
      else
        return {start: undefined, duration: undefined};
    }

    var duration;
    if (options[durationFieldName] !== undefined) {
      duration = options[durationFieldName];
    } else {
      duration = options[endFieldName] - options[startFieldName];
    }

    return {
      start: options[startFieldName],
      duration: duration
    };
  }

  function _maybeGetCpuStartAndCpuDurationFromDict(options) {
    return _getStartAndCpuDurationFromDict(
        options, false, 'cpuStart', 'cpuDuration', 'cpuEnd');
  }

  function TestUtils() {
  }

  TestUtils.getStartAndDurationFromDict = function(options) {
    return _getStartAndCpuDurationFromDict(
        options, true, 'start', 'duration', 'end');
  };

  TestUtils.newAsyncSlice = function(start, duration, startThread, endThread) {
    return TestUtils.newAsyncSliceNamed(
        'a', start, duration, startThread, endThread);
  };

  TestUtils.newAsyncSliceNamed = function(
      name, start, duration, startThread, endThread) {
    var asyncSliceConstructor =
        tr.model.AsyncSlice.getConstructor('', name);

    var s = new asyncSliceConstructor('', name, 0, start);
    s.duration = duration;
    s.startThread = startThread;
    s.endThread = endThread;
    return s;
  };

  function getColorId(colorId) {
    if (colorId) {
      if (colorId === 'random') {
        colorId = Math.floor(
            Math.random() *
            ColorScheme.proprties.numGeneralPurposeColorIds);
      }
    } else {
      colorId = 0;
    }
    return colorId;
  }

  TestUtils.newAsyncSliceEx = function(options) {
    var sd = TestUtils.getStartAndDurationFromDict(options);

    var cat = options.cat ? options.cat : 'cat';
    var title = options.title ? options.title : 'a';
    var colorId = getColorId(options.colorId);

    var isTopLevel;
    if (options.isTopLevel !== undefined)
      isTopLevel = options.isTopLevel;
    else
      isTopLevel = false;

    var asyncSliceConstructor =
        tr.model.AsyncSlice.getConstructor(cat, title);

    var slice = new asyncSliceConstructor(
        cat,
        title,
        colorId,
        sd.start,
        options.args ? options.args : {},
        sd.duration, isTopLevel);

    if (options.id)
      slice.id = options.id;
    else
      slice.id = tr.b.GUID.allocate();

    if (options.startStackFrame)
      slice.startStackFrame = options.startStackFrame;
    if (options.endStackFrame)
      slice.endStackFrame = options.endStackFrame;
    if (options.important)
      slice.important = options.important;
    if (options.startThread)
      slice.startThread = options.startThread;
    if (options.endThread)
      slice.endThread = options.endThread;
    return slice;
  };

  TestUtils.newCounter = function(parent) {
    return TestUtils.newCounterNamed(parent, 'a');
  };

  TestUtils.newCounterNamed = function(parent, name) {
    var s = new tr.model.Counter(parent, name, null, name);
    return s;
  };

  TestUtils.newCounterCategory = function(parent, category, name) {
    var s = new tr.model.Counter(parent, name, category, name);
    return s;
  };

  TestUtils.newCounterSeries = function() {
    var s = new tr.model.CounterSeries('a', 0);
    return s;
  };

  TestUtils.newFlowEventEx = function(options) {
    if (options.start === undefined)
      throw new Error('Too little info');

    var title = options.title ? options.title : 'a';

    var colorId = options.colorId ? options.colorId : 0;

    var sd = TestUtils.getStartAndDurationFromDict(options);

    var id;
    if (options.id !== undefined)
      id = options.id;
    else
      id = tr.b.GUID.allocate();

    var event = new tr.model.FlowEvent(
        options.cat ? options.cat : 'cat',
        id,
        title,
        colorId,
        sd.start,
        options.args ? options.args : {},
        sd.duration);

    if (options.startStackFrame)
      event.startStackFrame = options.startStackFrame;
    if (options.endStackFrame)
      event.endStackFrame = options.endStackFrame;
    if (options.important)
      event.important = options.important;
    if (options.startSlice) {
      event.startSlice = options.startSlice;
      event.startSlice.outFlowEvents.push(event);
    }
    if (options.endSlice) {
      event.endSlice = options.endSlice;
      event.endSlice.inFlowEvents.push(event);
    }
    return event;
  };

  TestUtils.newThreadSlice = function(thread, state, start, duration, opt_cpu) {
    var s = new tr.model.ThreadTimeSlice(
        thread, state, 'cat', start, {}, duration);
    if (opt_cpu)
      s.cpuOnWhichThreadWasRunning = opt_cpu;
    return s;
  };

  TestUtils.newSampleNamed = function(
      thread, sampleName, category, frameNames, start) {
    var model;
    if (thread.parent)
      model = thread.parent.model;
    else
      model = undefined;
    var sf = TestUtils.newStackTrace(model, frameNames);
    var s = new tr.model.Sample(undefined, thread,
                                        sampleName, start,
                                        sf,
                                        1);
    return s;
  };

  TestUtils.newSliceEx = function(options) {
    var sd = TestUtils.getStartAndDurationFromDict(options);

    var title = options.title ? options.title : 'a';

    var colorId = options.colorId ? options.colorId : 0;

    var cpuSD = _maybeGetCpuStartAndCpuDurationFromDict(options);

    var type;
    if (options.type)
      type = options.type;
    else
      type = tr.model.Slice;

    var slice = new type(
        options.cat ? options.cat : 'cat',
        title,
        colorId,
        sd.start,
        options.args ? options.args : {},
        sd.duration,
        cpuSD.start, cpuSD.duration);


    return slice;
  };

  TestUtils.newStackTrace = function(model, titles) {
    var frame = undefined;
    titles.forEach(function(title) {
      frame = new tr.model.StackFrame(frame, tr.b.GUID.allocate(), title, 7);
      if (model)
        model.addStackFrame(frame);
    });
    return frame;
  };

  TestUtils.findSliceNamed = function(slices, name) {
    if (slices instanceof tr.model.SliceGroup)
      slices = slices.slices;
    for (var i = 0; i < slices.length; i++)
      if (slices[i].title == name)
        return slices[i];
      return undefined;
  };

  TestUtils.newInteractionRecord = function(parentModel, start, duration) {
    return new tr.model.um.StubExpectation({
      parentModel: parentModel, start: start, duration: duration});
  };

  TestUtils.newModel = function(customizeModelCallback) {
    return TestUtils.newModelWithEvents([], {
      shiftWorldToZero: false,
      pruneEmptyContainers: false,
      customizeModelCallback: customizeModelCallback
    });
  };

  TestUtils.newModelWithEvents = function(events, opts) {
    if (!(events instanceof Array))
      events = [events];

    opts = opts || {};

    var io = new tr.importer.ImportOptions();
    io.showImportWarnings = false;
    io.customizeModelCallback = opts.customizeModelCallback;
    io.trackDetailedModelStats = opts.trackDetailedModelStats === undefined ?
        false : opts.trackDetailedModelStats;
    io.shiftWorldToZero = opts.shiftWorldToZero === undefined ?
        true : opts.shiftWorldToZero;
    io.pruneEmptyContainers = opts.pruneEmptyContainers === undefined ?
        true : opts.pruneEmptyContainers;
    io.auditorConstructors = opts.auditorConstructors === undefined ?
        [] : opts.auditorConstructors;

    var m = new tr.Model();
    var i = new tr.importer.Import(m, io);
    i.importTraces(events);
    return m;
  };

  TestUtils.newModelWithAuditor = function(customizeModelCallback, auditor) {
    return TestUtils.newModelWithEvents([], {
      shiftWorldToZero: false,
      pruneEmptyContainers: false,
      customizeModelCallback: customizeModelCallback,
      auditorConstructors: [auditor]
    });
  };

  TestUtils.newFakeThread = function() {
    var process = {model: {}};
    return new tr.model.Thread(process);
  };

  /** @constructor */
  TestUtils.SourceGenerator = function() {
    this.sourceList_ = [];
    this.currentLineCommentList_ = [];
    this.currentIndent_ = 0;
    this.currentLineEmpty_ = true;
  };

  TestUtils.SourceGenerator.prototype = {
    push: function(/* arguments */) {
      if (this.currentLineEmpty_) {
        this.sourceList_.push(' '.repeat(this.currentIndent_));
        this.currentLineEmpty_ = false;
      }
      this.sourceList_.push.apply(
          this.sourceList_, Array.prototype.slice.call(arguments));
    },

    pushComment: function(/* arguments */) {
      this.currentLineCommentList_.push.apply(
          this.currentLineCommentList_, Array.prototype.slice.call(arguments));
    },

    build: function() {
      this.finishLine_();
      return this.sourceList_.join('');
    },

    breakLine: function() {
      this.finishLine_();
      this.push('\n');
      this.currentLineEmpty_ = true;
    },

    finishLine_: function() {
      if (this.currentLineCommentList_.length === 0)
        return;
      this.push('  // ');
      this.push.apply(this, this.currentLineCommentList_);
      this.push('.');
      this.currentLineCommentList_ = [];
    },

    indentBlock: function(spaces, breakLine, blockCallback, opt_this) {
      opt_this = opt_this || this;
      this.currentIndent_ += spaces;
      if (breakLine)
        this.breakLine();
      blockCallback.call(opt_this);
      this.currentIndent_ -= spaces;
    },

    formatSingleLineList: function(list, itemCallback, opt_this) {
      opt_this = opt_this || this;
      this.push('[');
      tr.b.asArray(list).forEach(function(item, index) {
        if (index > 0)
          this.push(', ');
        itemCallback.call(opt_this, item, index);
      }, this);
      this.push(']');
    },

    formatMultiLineList: function(list, itemCallback, opt_this) {
      opt_this = opt_this || this;
      this.push('[');
      this.indentBlock(2, false /* don't break line */, function() {
        tr.b.asArray(list).forEach(function(item, index) {
          if (index > 0)
            this.push(',');
          this.breakLine();
          itemCallback.call(opt_this, item, index);
        }, this);
      }, this);
      if (list.length > 0)
        this.breakLine();
      this.push(']');
    },

    formatString: function(string) {
      if (string === undefined)
        this.push('undefined');
      else
        this.push('\'', string, '\'');
    }
  };

  TestUtils.addSourceListing = function(test, source) {
    var testSourceEl = document.createElement('pre');
    testSourceEl.style.fontFamily = 'monospace';
    testSourceEl.textContent = source;

    var copyButtonEl = document.createElement('button');
    copyButtonEl.textContent = 'Copy into to clipboard';
    copyButtonEl.addEventListener('click', function() {
      var selection = window.getSelection();

      // Store the original selection.
      var originalRanges = new Array(selection.rangeCount);
      for (var i = 0; i < originalRanges.length; i++)
        originalRanges[i] = selection.getRangeAt(i);

      // Copy the generated test source code into clipboard.
      selection.removeAllRanges();
      var range = document.createRange();
      range.selectNode(testSourceEl);
      selection.addRange(range);
      document.execCommand('copy');

      // Restore the original selection.
      selection.removeAllRanges();
      for (var i = 0; i < originalRanges.length; i++)
        selection.addRange(originalRanges[i]);
    });

    var outputEl = document.createElement('div');
    outputEl.appendChild(copyButtonEl);
    outputEl.appendChild(testSourceEl);
    test.addHTMLOutput(outputEl);
  };

  TestUtils.newInstantEvent = function(options) {
    var title = options.title;
    var start = options.start;
    if ((title === undefined) ||
        (title === '') ||
        (start === undefined))
      throw new Error('too little information');

    var category = options.category || 'category';
    var colorId = getColorId(options.colorId);
    var args = options.args || {};
    return new tr.model.InstantEvent(
        category, title, colorId, start, args);
  };

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