/*
 * Copyright (C) 2009 280 North Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
// Bottom Up Profiling shows the entire callstack backwards:
// The root node is a representation of each individual function called, and each child of that node represents
// a reverse-callstack showing how many of those calls came from it. So, unlike top-down, the statistics in
// each child still represent the root node. We have to be particularly careful of recursion with this mode
// because a root node can represent itself AND an ancestor.

/**
 * @unrestricted
 */
Profiler.BottomUpProfileDataGridNode = class extends Profiler.ProfileDataGridNode {
  /**
   * @param {!SDK.ProfileNode} profileNode
   * @param {!Profiler.TopDownProfileDataGridTree} owningTree
   */
  constructor(profileNode, owningTree) {
    super(profileNode, owningTree, !!profileNode.parent && !!profileNode.parent.parent);
    this._remainingNodeInfos = [];
  }

  /**
   * @param {!Profiler.BottomUpProfileDataGridNode|!Profiler.BottomUpProfileDataGridTree} container
   */
  static _sharedPopulate(container) {
    const remainingNodeInfos = container._remainingNodeInfos;
    const count = remainingNodeInfos.length;

    for (let index = 0; index < count; ++index) {
      const nodeInfo = remainingNodeInfos[index];
      const ancestor = nodeInfo.ancestor;
      const focusNode = nodeInfo.focusNode;
      let child = container.findChild(ancestor);

      // If we already have this child, then merge the data together.
      if (child) {
        const totalAccountedFor = nodeInfo.totalAccountedFor;

        child.self += focusNode.self;

        if (!totalAccountedFor) {
          child.total += focusNode.total;
        }
      } else {
        // If not, add it as a true ancestor.
        // In heavy mode, we take our visual identity from ancestor node...
        child = new Profiler.BottomUpProfileDataGridNode(
            ancestor, /** @type {!Profiler.TopDownProfileDataGridTree} */ (container.tree));

        if (ancestor !== focusNode) {
          // But the actual statistics from the "root" node (bottom of the callstack).
          child.self = focusNode.self;
          child.total = focusNode.total;
        }

        container.appendChild(child);
      }

      const parent = ancestor.parent;
      if (parent && parent.parent) {
        nodeInfo.ancestor = parent;
        child._remainingNodeInfos.push(nodeInfo);
      }
    }

    delete container._remainingNodeInfos;
  }

  /**
   * @param {!Profiler.ProfileDataGridNode} profileDataGridNode
   */
  _takePropertiesFromProfileDataGridNode(profileDataGridNode) {
    this.save();
    this.self = profileDataGridNode.self;
    this.total = profileDataGridNode.total;
  }

  /**
   * When focusing, we keep just the members of the callstack.
   * @param {!Profiler.ProfileDataGridNode} child
   */
  _keepOnlyChild(child) {
    this.save();

    this.removeChildren();
    this.appendChild(child);
  }

  /**
   * @param {string} aCallUID
   */
  _exclude(aCallUID) {
    if (this._remainingNodeInfos) {
      this.populate();
    }

    this.save();

    const children = this.children;
    let index = this.children.length;

    while (index--) {
      children[index]._exclude(aCallUID);
    }

    const child = this.childrenByCallUID.get(aCallUID);

    if (child) {
      this.merge(child, true);
    }
  }

  /**
   * @override
   */
  restore() {
    super.restore();

    if (!this.children.length) {
      this.setHasChildren(this._willHaveChildren(this.profileNode));
    }
  }

  /**
   * @override
   * @param {!Profiler.ProfileDataGridNode} child
   * @param {boolean} shouldAbsorb
   */
  merge(child, shouldAbsorb) {
    this.self -= child.self;
    super.merge(child, shouldAbsorb);
  }

  /**
   * @override
   */
  populateChildren() {
    Profiler.BottomUpProfileDataGridNode._sharedPopulate(this);
  }

  _willHaveChildren(profileNode) {
    // In bottom up mode, our parents are our children since we display an inverted tree.
    // However, we don't want to show the very top parent since it is redundant.
    return !!(profileNode.parent && profileNode.parent.parent);
  }
};


/**
 * @unrestricted
 */
Profiler.BottomUpProfileDataGridTree = class extends Profiler.ProfileDataGridTree {
  /**
   * @param {!Profiler.ProfileDataGridNode.Formatter} formatter
   * @param {!UI.SearchableView} searchableView
   * @param {!SDK.ProfileNode} rootProfileNode
   * @param {number} total
   */
  constructor(formatter, searchableView, rootProfileNode, total) {
    super(formatter, searchableView, total);
    this.deepSearch = false;

    // Iterate each node in pre-order.
    let profileNodeUIDs = 0;
    const profileNodeGroups = [[], [rootProfileNode]];
    /** @type {!Map<string, !Set<number>>} */
    const visitedProfileNodesForCallUID = new Map();

    this._remainingNodeInfos = [];

    for (let profileNodeGroupIndex = 0; profileNodeGroupIndex < profileNodeGroups.length; ++profileNodeGroupIndex) {
      const parentProfileNodes = profileNodeGroups[profileNodeGroupIndex];
      const profileNodes = profileNodeGroups[++profileNodeGroupIndex];
      const count = profileNodes.length;

      for (let index = 0; index < count; ++index) {
        const profileNode = profileNodes[index];

        if (!profileNode.UID) {
          profileNode.UID = ++profileNodeUIDs;
        }

        if (profileNode.parent) {
          // The total time of this ancestor is accounted for if we're in any form of recursive cycle.
          let visitedNodes = visitedProfileNodesForCallUID.get(profileNode.callUID);
          let totalAccountedFor = false;

          if (!visitedNodes) {
            visitedNodes = new Set();
            visitedProfileNodesForCallUID.set(profileNode.callUID, visitedNodes);
          } else {
            // The total time for this node has already been accounted for iff one of it's parents has already been visited.
            // We can do this check in this style because we are traversing the tree in pre-order.
            const parentCount = parentProfileNodes.length;
            for (let parentIndex = 0; parentIndex < parentCount; ++parentIndex) {
              if (visitedNodes.has(parentProfileNodes[parentIndex].UID)) {
                totalAccountedFor = true;
                break;
              }
            }
          }

          visitedNodes.add(profileNode.UID);

          this._remainingNodeInfos.push(
              {ancestor: profileNode, focusNode: profileNode, totalAccountedFor: totalAccountedFor});
        }

        const children = profileNode.children;
        if (children.length) {
          profileNodeGroups.push(parentProfileNodes.concat([profileNode]));
          profileNodeGroups.push(children);
        }
      }
    }

    // Populate the top level nodes.
    Profiler.ProfileDataGridNode.populate(this);

    return this;
  }

  /**
   * When focusing, we keep the entire callstack up to this ancestor.
   * @param {!Profiler.ProfileDataGridNode} profileDataGridNode
   */
  focus(profileDataGridNode) {
    if (!profileDataGridNode) {
      return;
    }

    this.save();

    let currentNode = profileDataGridNode;
    let focusNode = profileDataGridNode;

    while (currentNode.parent && (currentNode instanceof Profiler.ProfileDataGridNode)) {
      currentNode._takePropertiesFromProfileDataGridNode(profileDataGridNode);

      focusNode = currentNode;
      currentNode = currentNode.parent;

      if (currentNode instanceof Profiler.ProfileDataGridNode) {
        currentNode._keepOnlyChild(focusNode);
      }
    }

    this.children = [focusNode];
    this.total = profileDataGridNode.total;
  }

  /**
   * @param {!Profiler.ProfileDataGridNode} profileDataGridNode
   */
  exclude(profileDataGridNode) {
    if (!profileDataGridNode) {
      return;
    }

    this.save();

    const excludedCallUID = profileDataGridNode.callUID;
    const excludedTopLevelChild = this.childrenByCallUID.get(excludedCallUID);

    // If we have a top level node that is excluded, get rid of it completely (not keeping children),
    // since bottom up data relies entirely on the root node.
    if (excludedTopLevelChild) {
      this.children.remove(excludedTopLevelChild);
    }

    const children = this.children;
    const count = children.length;

    for (let index = 0; index < count; ++index) {
      children[index]._exclude(excludedCallUID);
    }

    if (this.lastComparator) {
      this.sort(this.lastComparator, true);
    }
  }

  /**
   * @override
   */
  populateChildren() {
    Profiler.BottomUpProfileDataGridNode._sharedPopulate(this);
  }
};
