<!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="/base/guid.html">
<link rel="import" href="/base/range.html">
<link rel="import" href="/model/counter.html">
<link rel="import" href="/model/event_container.html">
<link rel="import" href="/model/object_collection.html">
<link rel="import" href="/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.guid_ = tr.b.GUID.allocate();
    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 guid() {
      return this.guid_;
    },

    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>
