// Copyright 2016 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
 */
export class TracingLayerTree extends SDK.LayerTreeBase {
  /**
   * @param {?SDK.Target} target
   */
  constructor(target) {
    super(target);
    /** @type {!Map.<string, !TimelineModel.TracingLayerTile>} */
    this._tileById = new Map();
    this._paintProfilerModel = target && target.model(SDK.PaintProfilerModel);
  }

  /**
   * @param {?TimelineModel.TracingLayerPayload} root
   * @param {?Array<!TimelineModel.TracingLayerPayload>} layers
   * @param {!Array<!TimelineModel.LayerPaintEvent>} paints
   * @return {!Promise}
   */
  async setLayers(root, layers, paints) {
    const idsToResolve = new Set();
    if (root) {
      // This is a legacy code path for compatibility, as cc is removing
      // layer tree hierarchy, this code will eventually be removed.
      this._extractNodeIdsToResolve(idsToResolve, {}, root);
    } else {
      for (let i = 0; i < layers.length; ++i) {
        this._extractNodeIdsToResolve(idsToResolve, {}, layers[i]);
      }
    }

    await this.resolveBackendNodeIds(idsToResolve);

    const oldLayersById = this._layersById;
    this._layersById = {};
    this.setContentRoot(null);
    if (root) {
      const convertedLayers = this._innerSetLayers(oldLayersById, root);
      this.setRoot(convertedLayers);
    } else {
      const processedLayers = layers.map(this._innerSetLayers.bind(this, oldLayersById));
      const contentRoot = this.contentRoot();
      this.setRoot(contentRoot);
      for (let i = 0; i < processedLayers.length; ++i) {
        if (processedLayers[i].id() !== contentRoot.id()) {
          contentRoot.addChild(processedLayers[i]);
        }
      }
    }
    this._setPaints(paints);
  }

  /**
   * @param {!Array.<!TimelineModel.TracingLayerTile>} tiles
   */
  setTiles(tiles) {
    this._tileById = new Map();
    for (const tile of tiles) {
      this._tileById.set(tile.id, tile);
    }
  }

  /**
   * @param {string} tileId
   * @return {!Promise<?SDK.SnapshotWithRect>}
   */
  pictureForRasterTile(tileId) {
    const tile = this._tileById.get('cc::Tile/' + tileId);
    if (!tile) {
      Common.console.error(`Tile ${tileId} is missing`);
      return /** @type {!Promise<?SDK.SnapshotWithRect>} */ (Promise.resolve(null));
    }
    const layer = /** @type {?TracingLayer} */ (this.layerById(tile.layer_id));
    if (!layer) {
      Common.console.error(`Layer ${tile.layer_id} for tile ${tileId} is not found`);
      return /** @type {!Promise<?SDK.SnapshotWithRect>} */ (Promise.resolve(null));
    }
    return layer._pictureForRect(tile.content_rect);
  }

  /**
   * @param {!Array<!TimelineModel.LayerPaintEvent>} paints
   */
  _setPaints(paints) {
    for (let i = 0; i < paints.length; ++i) {
      const layer = this._layersById[paints[i].layerId()];
      if (layer) {
        layer._addPaintEvent(paints[i]);
      }
    }
  }

  /**
   * @param {!Object<(string|number), !SDK.Layer>} oldLayersById
   * @param {!TimelineModel.TracingLayerPayload} payload
   * @return {!TracingLayer}
   */
  _innerSetLayers(oldLayersById, payload) {
    let layer = /** @type {?TracingLayer} */ (oldLayersById[payload.layer_id]);
    if (layer) {
      layer._reset(payload);
    } else {
      layer = new TracingLayer(this._paintProfilerModel, payload);
    }
    this._layersById[payload.layer_id] = layer;
    if (payload.owner_node) {
      layer._setNode(this.backendNodeIdToNode().get(payload.owner_node) || null);
    }
    if (!this.contentRoot() && layer.drawsContent()) {
      this.setContentRoot(layer);
    }
    for (let i = 0; payload.children && i < payload.children.length; ++i) {
      layer.addChild(this._innerSetLayers(oldLayersById, payload.children[i]));
    }
    return layer;
  }

  /**
   * @param {!Set<number>} nodeIdsToResolve
   * @param {!Object} seenNodeIds
   * @param {!TimelineModel.TracingLayerPayload} payload
   */
  _extractNodeIdsToResolve(nodeIdsToResolve, seenNodeIds, payload) {
    const backendNodeId = payload.owner_node;
    if (backendNodeId && !this.backendNodeIdToNode().has(backendNodeId)) {
      nodeIdsToResolve.add(backendNodeId);
    }
    for (let i = 0; payload.children && i < payload.children.length; ++i) {
      this._extractNodeIdsToResolve(nodeIdsToResolve, seenNodeIds, payload.children[i]);
    }
  }
}

/**
 * @implements {SDK.Layer}
 * @unrestricted
 */
export class TracingLayer {
  /**
   * @param {?SDK.PaintProfilerModel} paintProfilerModel
   * @param {!TimelineModel.TracingLayerPayload} payload
   */
  constructor(paintProfilerModel, payload) {
    this._paintProfilerModel = paintProfilerModel;
    this._reset(payload);
  }

  /**
   * @param {!TimelineModel.TracingLayerPayload} payload
   */
  _reset(payload) {
    /** @type {?SDK.DOMNode} */
    this._node = null;
    this._layerId = String(payload.layer_id);
    this._offsetX = payload.position[0];
    this._offsetY = payload.position[1];
    this._width = payload.bounds.width;
    this._height = payload.bounds.height;
    this._children = [];
    this._parentLayerId = null;
    this._parent = null;
    this._quad = payload.layer_quad || [];
    this._createScrollRects(payload);

    // Keep payload.compositing_reasons as a default
    // but use the newer payload.debug_info.compositing_reasons
    // if the first one is not set.
    this._compositingReasons =
        payload.compositing_reasons || (payload.debug_info && payload.debug_info.compositing_reasons) || [];
    this._drawsContent = !!payload.draws_content;
    this._gpuMemoryUsage = payload.gpu_memory_usage;
    this._paints = [];
  }

  /**
   * @override
   * @return {string}
   */
  id() {
    return this._layerId;
  }

  /**
   * @override
   * @return {?string}
   */
  parentId() {
    return this._parentLayerId;
  }

  /**
   * @override
   * @return {?SDK.Layer}
   */
  parent() {
    return this._parent;
  }

  /**
   * @override
   * @return {boolean}
   */
  isRoot() {
    return !this.parentId();
  }

  /**
   * @override
   * @return {!Array.<!SDK.Layer>}
   */
  children() {
    return this._children;
  }

  /**
   * @override
   * @param {!SDK.Layer} childParam
   */
  addChild(childParam) {
    const child = /** @type {!TracingLayer} */ (childParam);
    if (child._parent) {
      console.assert(false, 'Child already has a parent');
    }
    this._children.push(child);
    child._parent = this;
    child._parentLayerId = this._layerId;
  }

  /**
   * @param {?SDK.DOMNode} node
   */
  _setNode(node) {
    this._node = node;
  }

  /**
   * @override
   * @return {?SDK.DOMNode}
   */
  node() {
    return this._node;
  }

  /**
   * @override
   * @return {?SDK.DOMNode}
   */
  nodeForSelfOrAncestor() {
    for (let layer = this; layer; layer = layer._parent) {
      if (layer._node) {
        return layer._node;
      }
    }
    return null;
  }

  /**
   * @override
   * @return {number}
   */
  offsetX() {
    return this._offsetX;
  }

  /**
   * @override
   * @return {number}
   */
  offsetY() {
    return this._offsetY;
  }

  /**
   * @override
   * @return {number}
   */
  width() {
    return this._width;
  }

  /**
   * @override
   * @return {number}
   */
  height() {
    return this._height;
  }

  /**
   * @override
   * @return {?Array.<number>}
   */
  transform() {
    return null;
  }

  /**
   * @override
   * @return {!Array.<number>}
   */
  quad() {
    return this._quad;
  }

  /**
   * @override
   * @return {!Array.<number>}
   */
  anchorPoint() {
    return [0.5, 0.5, 0];
  }

  /**
   * @override
   * @return {boolean}
   */
  invisible() {
    return false;
  }

  /**
   * @override
   * @return {number}
   */
  paintCount() {
    return 0;
  }

  /**
   * @override
   * @return {?Protocol.DOM.Rect}
   */
  lastPaintRect() {
    return null;
  }

  /**
   * @override
   * @return {!Array.<!Protocol.LayerTree.ScrollRect>}
   */
  scrollRects() {
    return this._scrollRects;
  }

  /**
   * @override
   * @return {?SDK.Layer.StickyPositionConstraint}
   */
  stickyPositionConstraint() {
    // TODO(smcgruer): Provide sticky layer information in traces.
    return null;
  }

  /**
   * @override
   * @return {number}
   */
  gpuMemoryUsage() {
    return this._gpuMemoryUsage;
  }

  /**
   * @override
   * @return {!Array<!Promise<?SDK.SnapshotWithRect>>}
   */
  snapshots() {
    return this._paints.map(paint => paint.snapshotPromise().then(snapshot => {
      if (!snapshot) {
        return null;
      }
      const rect = {x: snapshot.rect[0], y: snapshot.rect[1], width: snapshot.rect[2], height: snapshot.rect[3]};
      return {rect: rect, snapshot: snapshot.snapshot};
    }));
  }

  /**
   * @param {!Array<number>} targetRect
   * @return {!Promise<?SDK.SnapshotWithRect>}
   */
  _pictureForRect(targetRect) {
    return Promise.all(this._paints.map(paint => paint.picturePromise())).then(pictures => {
      const fragments =
          pictures.filter(picture => picture && rectsOverlap(picture.rect, targetRect))
              .map(picture => ({x: picture.rect[0], y: picture.rect[1], picture: picture.serializedPicture}));
      if (!fragments.length || !this._paintProfilerModel) {
        return null;
      }
      const x0 = fragments.reduce((min, item) => Math.min(min, item.x), Infinity);
      const y0 = fragments.reduce((min, item) => Math.min(min, item.y), Infinity);
      // Rect is in layer content coordinates, make it relative to picture by offsetting to the top left corner.
      const rect = {x: targetRect[0] - x0, y: targetRect[1] - y0, width: targetRect[2], height: targetRect[3]};
      return this._paintProfilerModel.loadSnapshotFromFragments(fragments).then(
          snapshot => snapshot ? {rect: rect, snapshot: snapshot} : null);
    });

    /**
     * @param {number} a1
     * @param {number} a2
     * @param {number} b1
     * @param {number} b2
     * @return {boolean}
     */
    function segmentsOverlap(a1, a2, b1, b2) {
      console.assert(a1 <= a2 && b1 <= b2, 'segments should be specified as ordered pairs');
      return a2 > b1 && a1 < b2;
    }

    /**
     * @param {!Array.<number>} a
     * @param {!Array.<number>} b
     * @return {boolean}
     */
    function rectsOverlap(a, b) {
      return segmentsOverlap(a[0], a[0] + a[2], b[0], b[0] + b[2]) &&
          segmentsOverlap(a[1], a[1] + a[3], b[1], b[1] + b[3]);
    }
  }

  /**
   * @param {!Array.<number>} params
   * @param {string} type
   * @return {!Object}
   */
  _scrollRectsFromParams(params, type) {
    return {rect: {x: params[0], y: params[1], width: params[2], height: params[3]}, type: type};
  }

  /**
   * @param {!TimelineModel.TracingLayerPayload} payload
   */
  _createScrollRects(payload) {
    this._scrollRects = [];
    if (payload.non_fast_scrollable_region) {
      this._scrollRects.push(this._scrollRectsFromParams(
          payload.non_fast_scrollable_region, SDK.Layer.ScrollRectType.NonFastScrollable.name));
    }
    if (payload.touch_event_handler_region) {
      this._scrollRects.push(this._scrollRectsFromParams(
          payload.touch_event_handler_region, SDK.Layer.ScrollRectType.TouchEventHandler.name));
    }
    if (payload.wheel_event_handler_region) {
      this._scrollRects.push(this._scrollRectsFromParams(
          payload.wheel_event_handler_region, SDK.Layer.ScrollRectType.WheelEventHandler.name));
    }
    if (payload.scroll_event_handler_region) {
      this._scrollRects.push(this._scrollRectsFromParams(
          payload.scroll_event_handler_region, SDK.Layer.ScrollRectType.RepaintsOnScroll.name));
    }
  }

  /**
   * @param {!TimelineModel.LayerPaintEvent} paint
   */
  _addPaintEvent(paint) {
    this._paints.push(paint);
  }

  /**
   * @override
   * @return {!Promise<!Array<string>>}
   */
  requestCompositingReasons() {
    return Promise.resolve(this._compositingReasons);
  }

  /**
   * @override
   * @return {boolean}
   */
  drawsContent() {
    return this._drawsContent;
  }
}

/* Legacy exported object */
self.TimelineModel = self.TimelineModel || {};

/* Legacy exported object */
TimelineModel = TimelineModel || {};

/** @constructor */
TimelineModel.TracingLayerTree = TracingLayerTree;

/** @constructor */
TimelineModel.TracingLayer = TracingLayer;

/** @typedef {!{
        bounds: {height: number, width: number},
        children: Array.<!TimelineModel.TracingLayerPayload>,
        layer_id: number,
        position: Array.<number>,
        scroll_offset: Array.<number>,
        layer_quad: Array.<number>,
        draws_content: number,
        gpu_memory_usage: number,
        transform: Array.<number>,
        owner_node: number,
        compositing_reasons: Array.<string>
    }}
*/
TimelineModel.TracingLayerPayload;

/** @typedef {!{
        id: string,
        layer_id: string,
        gpu_memory_usage: number,
        content_rect: !Array.<number>
    }}
*/
TimelineModel.TracingLayerTile;
