// Copyright 2014 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.
/**
 * @unrestricted
 */
SDK.CPUProfileNode = class extends SDK.ProfileNode {
  /**
   * @param {!Protocol.Profiler.ProfileNode} node
   * @param {number} sampleTime
   */
  constructor(node, sampleTime) {
    const callFrame = node.callFrame || /** @type {!Protocol.Runtime.CallFrame} */ ({
                        // Backward compatibility for old SamplingHeapProfileNode format.
                        functionName: node['functionName'],
                        scriptId: node['scriptId'],
                        url: node['url'],
                        lineNumber: node['lineNumber'] - 1,
                        columnNumber: node['columnNumber'] - 1
                      });
    super(callFrame);
    this.id = node.id;
    this.self = node.hitCount * sampleTime;
    this.positionTicks = node.positionTicks;
    // Compatibility: legacy backends could provide "no reason" for optimized functions.
    this.deoptReason = node.deoptReason && node.deoptReason !== 'no reason' ? node.deoptReason : null;
  }
};

/**
 * @unrestricted
 */
SDK.CPUProfileDataModel = class extends SDK.ProfileTreeModel {
  /**
   * @param {!Protocol.Profiler.Profile} profile
   */
  constructor(profile) {
    super();
    const isLegacyFormat = !!profile['head'];
    if (isLegacyFormat) {
      // Legacy format contains raw timestamps and start/stop times are in seconds.
      this.profileStartTime = profile.startTime * 1000;
      this.profileEndTime = profile.endTime * 1000;
      this.timestamps = profile.timestamps;
      this._compatibilityConversionHeadToNodes(profile);
    } else {
      // Current format encodes timestamps as deltas. Start/stop times are in microseconds.
      this.profileStartTime = profile.startTime / 1000;
      this.profileEndTime = profile.endTime / 1000;
      this.timestamps = this._convertTimeDeltas(profile);
    }
    this.samples = profile.samples;
    this.totalHitCount = 0;
    this.profileHead = this._translateProfileTree(profile.nodes);
    this.initialize(this.profileHead);
    this._extractMetaNodes();
    if (this.samples) {
      this._buildIdToNodeMap();
      this._sortSamples();
      this._normalizeTimestamps();
      this._fixMissingSamples();
    }
  }

  /**
   * @param {!Protocol.Profiler.Profile} profile
   */
  _compatibilityConversionHeadToNodes(profile) {
    if (!profile.head || profile.nodes)
      return;
    /** @type {!Array<!Protocol.Profiler.ProfileNode>} */
    const nodes = [];
    convertNodesTree(profile.head);
    profile.nodes = nodes;
    delete profile.head;
    /**
     * @param {!Protocol.Profiler.ProfileNode} node
     * @return {number}
     */
    function convertNodesTree(node) {
      nodes.push(node);
      node.children = (/** @type {!Array<!Protocol.Profiler.ProfileNode>} */ (node.children)).map(convertNodesTree);
      return node.id;
    }
  }

  /**
   * @param {!Protocol.Profiler.Profile} profile
   * @return {?Array<number>}
   */
  _convertTimeDeltas(profile) {
    if (!profile.timeDeltas)
      return null;
    let lastTimeUsec = profile.startTime;
    const timestamps = new Array(profile.timeDeltas.length);
    for (let i = 0; i < profile.timeDeltas.length; ++i) {
      lastTimeUsec += profile.timeDeltas[i];
      timestamps[i] = lastTimeUsec;
    }
    return timestamps;
  }

  /**
   * @param {!Array<!Protocol.Profiler.ProfileNode>} nodes
   * @return {!SDK.CPUProfileNode}
   */
  _translateProfileTree(nodes) {
    /**
     * @param {!Protocol.Profiler.ProfileNode} node
     * @return {boolean}
     */
    function isNativeNode(node) {
      if (node.callFrame)
        return !!node.callFrame.url && node.callFrame.url.startsWith('native ');
      return !!node['url'] && node['url'].startsWith('native ');
    }
    /**
     * @param {!Array<!Protocol.Profiler.ProfileNode>} nodes
     */
    function buildChildrenFromParents(nodes) {
      if (nodes[0].children)
        return;
      nodes[0].children = [];
      for (let i = 1; i < nodes.length; ++i) {
        const node = nodes[i];
        const parentNode = nodeByIdMap.get(node.parent);
        if (parentNode.children)
          parentNode.children.push(node.id);
        else
          parentNode.children = [node.id];
      }
    }
    /** @type {!Map<number, !Protocol.Profiler.ProfileNode>} */
    const nodeByIdMap = new Map();
    for (let i = 0; i < nodes.length; ++i) {
      const node = nodes[i];
      nodeByIdMap.set(node.id, node);
    }
    buildChildrenFromParents(nodes);
    this.totalHitCount = nodes.reduce((acc, node) => acc + node.hitCount, 0);
    const sampleTime = (this.profileEndTime - this.profileStartTime) / this.totalHitCount;
    const keepNatives = !!Common.moduleSetting('showNativeFunctionsInJSProfile').get();
    const root = nodes[0];
    /** @type {!Map<number, number>} */
    const idMap = new Map([[root.id, root.id]]);
    const resultRoot = new SDK.CPUProfileNode(root, sampleTime);
    const parentNodeStack = root.children.map(() => resultRoot);
    const sourceNodeStack = root.children.map(id => nodeByIdMap.get(id));
    while (sourceNodeStack.length) {
      let parentNode = parentNodeStack.pop();
      const sourceNode = sourceNodeStack.pop();
      if (!sourceNode.children)
        sourceNode.children = [];
      const targetNode = new SDK.CPUProfileNode(sourceNode, sampleTime);
      if (keepNatives || !isNativeNode(sourceNode)) {
        parentNode.children.push(targetNode);
        parentNode = targetNode;
      } else {
        parentNode.self += targetNode.self;
      }
      idMap.set(sourceNode.id, parentNode.id);
      parentNodeStack.push.apply(parentNodeStack, sourceNode.children.map(() => parentNode));
      sourceNodeStack.push.apply(sourceNodeStack, sourceNode.children.map(id => nodeByIdMap.get(id)));
    }
    if (this.samples)
      this.samples = this.samples.map(id => idMap.get(id));
    return resultRoot;
  }

  _sortSamples() {
    const timestamps = this.timestamps;
    if (!timestamps)
      return;
    const samples = this.samples;
    const indices = timestamps.map((x, index) => index);
    indices.stableSort((a, b) => timestamps[a] - timestamps[b]);
    for (let i = 0; i < timestamps.length; ++i) {
      let index = indices[i];
      if (index === i)
        continue;
      // Move items in a cycle.
      const savedTimestamp = timestamps[i];
      const savedSample = samples[i];
      let currentIndex = i;
      while (index !== i) {
        samples[currentIndex] = samples[index];
        timestamps[currentIndex] = timestamps[index];
        currentIndex = index;
        index = indices[index];
        indices[currentIndex] = currentIndex;
      }
      samples[currentIndex] = savedSample;
      timestamps[currentIndex] = savedTimestamp;
    }
  }

  _normalizeTimestamps() {
    let timestamps = this.timestamps;
    if (!timestamps) {
      // Support loading old CPU profiles that are missing timestamps.
      // Derive timestamps from profile start and stop times.
      const profileStartTime = this.profileStartTime;
      const interval = (this.profileEndTime - profileStartTime) / this.samples.length;
      timestamps = new Float64Array(this.samples.length + 1);
      for (let i = 0; i < timestamps.length; ++i)
        timestamps[i] = profileStartTime + i * interval;
      this.timestamps = timestamps;
      return;
    }

    // Convert samples from usec to msec
    for (let i = 0; i < timestamps.length; ++i)
      timestamps[i] /= 1000;
    if (this.samples.length === timestamps.length) {
      // Support for a legacy format where were no timeDeltas.
      // Add an extra timestamp used to calculate the last sample duration.
      const averageSample = (timestamps.peekLast() - timestamps[0]) / (timestamps.length - 1);
      this.timestamps.push(timestamps.peekLast() + averageSample);
    }
    this.profileStartTime = timestamps[0];
    this.profileEndTime = timestamps.peekLast();
  }

  _buildIdToNodeMap() {
    /** @type {!Map<number, !SDK.CPUProfileNode>} */
    this._idToNode = new Map();
    const idToNode = this._idToNode;
    const stack = [this.profileHead];
    while (stack.length) {
      const node = stack.pop();
      idToNode.set(node.id, node);
      stack.push.apply(stack, node.children);
    }
  }

  _extractMetaNodes() {
    const topLevelNodes = this.profileHead.children;
    for (let i = 0; i < topLevelNodes.length && !(this.gcNode && this.programNode && this.idleNode); i++) {
      const node = topLevelNodes[i];
      if (node.functionName === '(garbage collector)')
        this.gcNode = node;
      else if (node.functionName === '(program)')
        this.programNode = node;
      else if (node.functionName === '(idle)')
        this.idleNode = node;
    }
  }

  _fixMissingSamples() {
    // Sometimes sampler is not able to parse the JS stack and returns
    // a (program) sample instead. The issue leads to call frames belong
    // to the same function invocation being split apart.
    // Here's a workaround for that. When there's a single (program) sample
    // between two call stacks sharing the same bottom node, it is replaced
    // with the preceeding sample.
    const samples = this.samples;
    const samplesCount = samples.length;
    if (!this.programNode || samplesCount < 3)
      return;
    const idToNode = this._idToNode;
    const programNodeId = this.programNode.id;
    const gcNodeId = this.gcNode ? this.gcNode.id : -1;
    const idleNodeId = this.idleNode ? this.idleNode.id : -1;
    let prevNodeId = samples[0];
    let nodeId = samples[1];
    let count = 0;
    for (let sampleIndex = 1; sampleIndex < samplesCount - 1; sampleIndex++) {
      const nextNodeId = samples[sampleIndex + 1];
      if (nodeId === programNodeId && !isSystemNode(prevNodeId) && !isSystemNode(nextNodeId) &&
          bottomNode(idToNode.get(prevNodeId)) === bottomNode(idToNode.get(nextNodeId))) {
        ++count;
        samples[sampleIndex] = prevNodeId;
      }
      prevNodeId = nodeId;
      nodeId = nextNodeId;
    }
    if (count)
      Common.console.warn(ls`DevTools: CPU profile parser is fixing ${count} missing samples.`);
    /**
     * @param {!SDK.ProfileNode} node
     * @return {!SDK.ProfileNode}
     */
    function bottomNode(node) {
      while (node.parent && node.parent.parent)
        node = node.parent;
      return node;
    }
    /**
     * @param {number} nodeId
     * @return {boolean}
     */
    function isSystemNode(nodeId) {
      return nodeId === programNodeId || nodeId === gcNodeId || nodeId === idleNodeId;
    }
  }

  /**
   * @param {function(number, !SDK.CPUProfileNode, number)} openFrameCallback
   * @param {function(number, !SDK.CPUProfileNode, number, number, number)} closeFrameCallback
   * @param {number=} startTime
   * @param {number=} stopTime
   */
  forEachFrame(openFrameCallback, closeFrameCallback, startTime, stopTime) {
    if (!this.profileHead || !this.samples)
      return;

    startTime = startTime || 0;
    stopTime = stopTime || Infinity;
    const samples = this.samples;
    const timestamps = this.timestamps;
    const idToNode = this._idToNode;
    const gcNode = this.gcNode;
    const samplesCount = samples.length;
    const startIndex = timestamps.lowerBound(startTime);
    let stackTop = 0;
    const stackNodes = [];
    let prevId = this.profileHead.id;
    let sampleTime;
    let gcParentNode = null;

    // Extra slots for gc being put on top,
    // and one at the bottom to allow safe stackTop-1 access.
    const stackDepth = this.maxDepth + 3;
    if (!this._stackStartTimes)
      this._stackStartTimes = new Float64Array(stackDepth);
    const stackStartTimes = this._stackStartTimes;
    if (!this._stackChildrenDuration)
      this._stackChildrenDuration = new Float64Array(stackDepth);
    const stackChildrenDuration = this._stackChildrenDuration;

    let node;
    let sampleIndex;
    for (sampleIndex = startIndex; sampleIndex < samplesCount; sampleIndex++) {
      sampleTime = timestamps[sampleIndex];
      if (sampleTime >= stopTime)
        break;
      const id = samples[sampleIndex];
      if (id === prevId)
        continue;
      node = idToNode.get(id);
      let prevNode = idToNode.get(prevId);

      if (node === gcNode) {
        // GC samples have no stack, so we just put GC node on top of the last recorded sample.
        gcParentNode = prevNode;
        openFrameCallback(gcParentNode.depth + 1, gcNode, sampleTime);
        stackStartTimes[++stackTop] = sampleTime;
        stackChildrenDuration[stackTop] = 0;
        prevId = id;
        continue;
      }
      if (prevNode === gcNode) {
        // end of GC frame
        const start = stackStartTimes[stackTop];
        const duration = sampleTime - start;
        stackChildrenDuration[stackTop - 1] += duration;
        closeFrameCallback(gcParentNode.depth + 1, gcNode, start, duration, duration - stackChildrenDuration[stackTop]);
        --stackTop;
        prevNode = gcParentNode;
        prevId = prevNode.id;
        gcParentNode = null;
      }

      while (node.depth > prevNode.depth) {
        stackNodes.push(node);
        node = node.parent;
      }

      // Go down to the LCA and close current intervals.
      while (prevNode !== node) {
        const start = stackStartTimes[stackTop];
        const duration = sampleTime - start;
        stackChildrenDuration[stackTop - 1] += duration;
        closeFrameCallback(
            prevNode.depth, /** @type {!SDK.CPUProfileNode} */ (prevNode), start, duration,
            duration - stackChildrenDuration[stackTop]);
        --stackTop;
        if (node.depth === prevNode.depth) {
          stackNodes.push(node);
          node = node.parent;
        }
        prevNode = prevNode.parent;
      }

      // Go up the nodes stack and open new intervals.
      while (stackNodes.length) {
        node = stackNodes.pop();
        openFrameCallback(node.depth, node, sampleTime);
        stackStartTimes[++stackTop] = sampleTime;
        stackChildrenDuration[stackTop] = 0;
      }

      prevId = id;
    }

    sampleTime = timestamps[sampleIndex] || this.profileEndTime;
    if (idToNode.get(prevId) === gcNode) {
      const start = stackStartTimes[stackTop];
      const duration = sampleTime - start;
      stackChildrenDuration[stackTop - 1] += duration;
      closeFrameCallback(gcParentNode.depth + 1, node, start, duration, duration - stackChildrenDuration[stackTop]);
      --stackTop;
      prevId = gcParentNode.id;
    }

    for (let node = idToNode.get(prevId); node.parent; node = node.parent) {
      const start = stackStartTimes[stackTop];
      const duration = sampleTime - start;
      stackChildrenDuration[stackTop - 1] += duration;
      closeFrameCallback(
          node.depth, /** @type {!SDK.CPUProfileNode} */ (node), start, duration,
          duration - stackChildrenDuration[stackTop]);
      --stackTop;
    }
  }

  /**
   * @param {number} index
   * @return {?SDK.CPUProfileNode}
   */
  nodeByIndex(index) {
    return this._idToNode.get(this.samples[index]) || null;
  }
};
