<!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="/tracing/base/guid.html">
<link rel="import" href="/tracing/base/range.html">
<link rel="import" href="/tracing/model/counter.html">
<link rel="import" href="/tracing/model/event_container.html">
<link rel="import" href="/tracing/model/object_collection.html">
<link rel="import" href="/tracing/model/thread.html">

<script>
'use strict';

/**
 * @fileoverview Provides the ProcessBase class.
 */
tr.exportTo('tr.model', function() {

  var Thread = tr.model.Thread;
  var Counter = tr.model.Counter;

  /**
   * The ProcessBase is a partial base class, upon which Kernel
   * and Process are built.
   *
   * @constructor
   * @extends {tr.model.EventContainer}
   */
  function ProcessBase(model) {
    if (!model)
      throw new Error('Must provide a model');
    tr.model.EventContainer.call(this);
    this.model = model;
    this.threads = {};
    this.counters = {};
    this.objects = new tr.model.ObjectCollection(this);
    this.sortIndex = 0;
  };

  ProcessBase.compare = function(x, y) {
    return x.sortIndex - y.sortIndex;
  };

  ProcessBase.prototype = {
    __proto__: tr.model.EventContainer.prototype,

    get stableId() {
      throw new Error('Not implemented');
    },

    iterateAllChildEventContainers: function(callback, opt_this) {
      for (var tid in this.threads)
        callback.call(opt_this, this.threads[tid]);
      for (var id in this.counters)
        callback.call(opt_this, this.counters[id]);
      callback.call(opt_this, this.objects);
    },

    iterateAllEventsInThisContainer: function(eventTypePredicate,
                                              callback, opt_this) {
    },

    iterateAllPersistableObjects: function(cb) {
      cb(this);
      for (var tid in this.threads)
        this.threads[tid].iterateAllPersistableObjects(cb);
    },

    /**
     * Gets the number of threads in this process.
     */
    get numThreads() {
      var n = 0;
      for (var p in this.threads) {
        n++;
      }
      return n;
    },

    /**
     * Shifts all the timestamps inside this process forward by the amount
     * specified.
     */
    shiftTimestampsForward: function(amount) {
      this.iterateAllChildEventContainers(function(child) {
        child.shiftTimestampsForward(amount);
      });
    },

    /**
     * Closes any open slices.
     */
    autoCloseOpenSlices: function(opt_maxTimestamp) {
      for (var tid in this.threads) {
        var thread = this.threads[tid];
        thread.autoCloseOpenSlices(opt_maxTimestamp);
      }
    },

    autoDeleteObjects: function(maxTimestamp) {
      this.objects.autoDeleteObjects(maxTimestamp);
    },

    /**
     * Called by the model after finalizing imports,
     * but before joining refs.
     */
    preInitializeObjects: function() {
      this.objects.preInitializeAllObjects();
    },

    /**
     * Called by the model after joining refs.
     */
    initializeObjects: function() {
      this.objects.initializeAllObjects();
    },

    /**
     * Merge slices from the kernel with those from userland for each thread.
     */
    mergeKernelWithUserland: function() {
      for (var tid in this.threads) {
        var thread = this.threads[tid];
        thread.mergeKernelWithUserland();
      }
    },

    updateBounds: function() {
      this.bounds.reset();
      for (var tid in this.threads) {
        this.threads[tid].updateBounds();
        this.bounds.addRange(this.threads[tid].bounds);
      }
      for (var id in this.counters) {
        this.counters[id].updateBounds();
        this.bounds.addRange(this.counters[id].bounds);
      }
      this.objects.updateBounds();
      this.bounds.addRange(this.objects.bounds);
    },

    addCategoriesToDict: function(categoriesDict) {
      for (var tid in this.threads)
        this.threads[tid].addCategoriesToDict(categoriesDict);
      for (var id in this.counters)
        categoriesDict[this.counters[id].category] = true;
      this.objects.addCategoriesToDict(categoriesDict);
    },

    findAllThreadsMatching: function(predicate, opt_this) {
      var threads = [];
      for (var tid in this.threads) {
        var thread = this.threads[tid];
        if (predicate.call(opt_this, thread))
          threads.push(thread);
      }
      return threads;
    },

    /**
     * @param {String} The name of the thread to find.
     * @return {Array} An array of all the matched threads.
     */
    findAllThreadsNamed: function(name) {
      var threads = this.findAllThreadsMatching(function(thread) {
        if (!thread.name)
          return false;
        return thread.name === name;
      });
      return threads;
    },

    findAtMostOneThreadNamed: function(name) {
      var threads = this.findAllThreadsNamed(name);
      if (threads.length === 0)
        return undefined;
      if (threads.length > 1)
        throw new Error('Expected no more than one ' + name);
      return threads[0];
    },

    /**
     * Removes threads from the process that are fully empty.
     */
    pruneEmptyContainers: function() {
      var threadsToKeep = {};
      for (var tid in this.threads) {
        var thread = this.threads[tid];
        if (!thread.isEmpty)
          threadsToKeep[tid] = thread;
      }
      this.threads = threadsToKeep;
    },

    /**
     * @return {TimelineThread} The thread identified by tid on this process,
     * or undefined if it doesn't exist.
     */
    getThread: function(tid) {
      return this.threads[tid];
    },

    /**
     * @return {TimelineThread} The thread identified by tid on this process,
     * creating it if it doesn't exist.
     */
    getOrCreateThread: function(tid) {
      if (!this.threads[tid])
        this.threads[tid] = new Thread(this, tid);
      return this.threads[tid];
    },

    /**
     * @return {Counter} The counter on this process with the given
     * category/name combination, creating it if it doesn't exist.
     */
    getOrCreateCounter: function(cat, name) {
      var id = cat + '.' + name;
      if (!this.counters[id])
        this.counters[id] = new Counter(this, id, cat, name);
      return this.counters[id];
    },

    getSettingsKey: function() {
      throw new Error('Not implemented');
    },

    createSubSlices: function() {
      for (var tid in this.threads)
        this.threads[tid].createSubSlices();
    }
  };

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