/*
 * Copyright (C) 2013 Google 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "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 THE COPYRIGHT
 * OWNER 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.
 */

/**
 * @unrestricted
 */
export class PaintProfilerView extends UI.HBox {
  /**
   * @param {function(string=)} showImageCallback
   */
  constructor(showImageCallback) {
    super(true);
    this.registerRequiredCSS('layer_viewer/paintProfiler.css');
    this.contentElement.classList.add('paint-profiler-overview');
    this._canvasContainer = this.contentElement.createChild('div', 'paint-profiler-canvas-container');
    this._progressBanner = this.contentElement.createChild('div', 'full-widget-dimmed-banner hidden');
    this._progressBanner.textContent = Common.UIString('Profiling\u2026');
    this._pieChart = new PerfUI.PieChart(
        {chartName: ls`Profiling Results`, size: 55, formatter: this._formatPieChartTime.bind(this)});
    this._pieChart.element.classList.add('paint-profiler-pie-chart');
    this.contentElement.appendChild(this._pieChart.element);

    this._showImageCallback = showImageCallback;

    this._canvas = this._canvasContainer.createChild('canvas', 'fill');
    this._context = this._canvas.getContext('2d');
    this._selectionWindow = new PerfUI.OverviewGrid.Window(this._canvasContainer);
    this._selectionWindow.addEventListener(PerfUI.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);

    this._innerBarWidth = 4 * window.devicePixelRatio;
    this._minBarHeight = window.devicePixelRatio;
    this._barPaddingWidth = 2 * window.devicePixelRatio;
    this._outerBarWidth = this._innerBarWidth + this._barPaddingWidth;
    this._pendingScale = 1;
    this._scale = this._pendingScale;

    this._reset();
  }

  /**
   * @return {!Object.<string, !LayerViewer.PaintProfilerCategory>}
   */
  static categories() {
    if (PaintProfilerView._categories) {
      return PaintProfilerView._categories;
    }
    PaintProfilerView._categories = {
      shapes: new PaintProfilerCategory('shapes', Common.UIString('Shapes'), 'rgb(255, 161, 129)'),
      bitmap: new PaintProfilerCategory('bitmap', Common.UIString('Bitmap'), 'rgb(136, 196, 255)'),
      text: new PaintProfilerCategory('text', Common.UIString('Text'), 'rgb(180, 255, 137)'),
      misc: new PaintProfilerCategory('misc', Common.UIString('Misc'), 'rgb(206, 160, 255)')
    };
    return PaintProfilerView._categories;
  }

  /**
   * @return {!Object.<string, !LayerViewer.PaintProfilerCategory>}
   */
  static _initLogItemCategories() {
    if (PaintProfilerView._logItemCategoriesMap) {
      return PaintProfilerView._logItemCategoriesMap;
    }

    const categories = PaintProfilerView.categories();

    const logItemCategories = {};
    logItemCategories['Clear'] = categories['misc'];
    logItemCategories['DrawPaint'] = categories['misc'];
    logItemCategories['DrawData'] = categories['misc'];
    logItemCategories['SetMatrix'] = categories['misc'];
    logItemCategories['PushCull'] = categories['misc'];
    logItemCategories['PopCull'] = categories['misc'];
    logItemCategories['Translate'] = categories['misc'];
    logItemCategories['Scale'] = categories['misc'];
    logItemCategories['Concat'] = categories['misc'];
    logItemCategories['Restore'] = categories['misc'];
    logItemCategories['SaveLayer'] = categories['misc'];
    logItemCategories['Save'] = categories['misc'];
    logItemCategories['BeginCommentGroup'] = categories['misc'];
    logItemCategories['AddComment'] = categories['misc'];
    logItemCategories['EndCommentGroup'] = categories['misc'];
    logItemCategories['ClipRect'] = categories['misc'];
    logItemCategories['ClipRRect'] = categories['misc'];
    logItemCategories['ClipPath'] = categories['misc'];
    logItemCategories['ClipRegion'] = categories['misc'];
    logItemCategories['DrawPoints'] = categories['shapes'];
    logItemCategories['DrawRect'] = categories['shapes'];
    logItemCategories['DrawOval'] = categories['shapes'];
    logItemCategories['DrawRRect'] = categories['shapes'];
    logItemCategories['DrawPath'] = categories['shapes'];
    logItemCategories['DrawVertices'] = categories['shapes'];
    logItemCategories['DrawDRRect'] = categories['shapes'];
    logItemCategories['DrawBitmap'] = categories['bitmap'];
    logItemCategories['DrawBitmapRectToRect'] = categories['bitmap'];
    logItemCategories['DrawBitmapMatrix'] = categories['bitmap'];
    logItemCategories['DrawBitmapNine'] = categories['bitmap'];
    logItemCategories['DrawSprite'] = categories['bitmap'];
    logItemCategories['DrawPicture'] = categories['bitmap'];
    logItemCategories['DrawText'] = categories['text'];
    logItemCategories['DrawPosText'] = categories['text'];
    logItemCategories['DrawPosTextH'] = categories['text'];
    logItemCategories['DrawTextOnPath'] = categories['text'];

    PaintProfilerView._logItemCategoriesMap = logItemCategories;
    return logItemCategories;
  }

  /**
   * @param {!Object} logItem
   * @return {!LayerViewer.PaintProfilerCategory}
   */
  static _categoryForLogItem(logItem) {
    const method = logItem.method.toTitleCase();

    const logItemCategories = PaintProfilerView._initLogItemCategories();
    let result = logItemCategories[method];
    if (!result) {
      result = PaintProfilerView.categories()['misc'];
      logItemCategories[method] = result;
    }
    return result;
  }

  /**
   * @override
   */
  onResize() {
    this._update();
  }

  /**
   * @param {?SDK.PaintProfilerSnapshot} snapshot
   * @param {!Array.<!SDK.PaintProfilerLogItem>} log
   * @param {?Protocol.DOM.Rect} clipRect
   */
  async setSnapshotAndLog(snapshot, log, clipRect) {
    this._reset();
    this._snapshot = snapshot;
    if (this._snapshot) {
      this._snapshot.addReference();
    }
    this._log = log;
    this._logCategories = this._log.map(PaintProfilerView._categoryForLogItem);

    if (!this._snapshot) {
      this._update();
      this._pieChart.setTotal(0);
      this._selectionWindow.setEnabled(false);
      return;
    }
    this._selectionWindow.setEnabled(true);
    this._progressBanner.classList.remove('hidden');
    this._updateImage();

    const profiles = await snapshot.profile(clipRect);

    this._progressBanner.classList.add('hidden');
    this._profiles = profiles;
    this._update();
    this._updatePieChart();
  }

  /**
   * @param {number} scale
   */
  setScale(scale) {
    const needsUpdate = scale > this._scale;
    const predictiveGrowthFactor = 2;
    this._pendingScale = Math.min(1, scale * predictiveGrowthFactor);
    if (needsUpdate && this._snapshot) {
      this._updateImage();
    }
  }

  _update() {
    this._canvas.width = this._canvasContainer.clientWidth * window.devicePixelRatio;
    this._canvas.height = this._canvasContainer.clientHeight * window.devicePixelRatio;
    this._samplesPerBar = 0;
    if (!this._profiles || !this._profiles.length) {
      return;
    }

    const maxBars = Math.floor((this._canvas.width - 2 * this._barPaddingWidth) / this._outerBarWidth);
    const sampleCount = this._log.length;
    this._samplesPerBar = Math.ceil(sampleCount / maxBars);

    let maxBarTime = 0;
    const barTimes = [];
    const barHeightByCategory = [];
    let heightByCategory = {};
    for (let i = 0, lastBarIndex = 0, lastBarTime = 0; i < sampleCount;) {
      let categoryName = (this._logCategories[i] && this._logCategories[i].name) || 'misc';
      const sampleIndex = this._log[i].commandIndex;
      for (let row = 0; row < this._profiles.length; row++) {
        const sample = this._profiles[row][sampleIndex];
        lastBarTime += sample;
        heightByCategory[categoryName] = (heightByCategory[categoryName] || 0) + sample;
      }
      ++i;
      if (i - lastBarIndex === this._samplesPerBar || i === sampleCount) {
        // Normalize by total number of samples accumulated.
        const factor = this._profiles.length * (i - lastBarIndex);
        lastBarTime /= factor;
        for (categoryName in heightByCategory) {
          heightByCategory[categoryName] /= factor;
        }

        barTimes.push(lastBarTime);
        barHeightByCategory.push(heightByCategory);

        if (lastBarTime > maxBarTime) {
          maxBarTime = lastBarTime;
        }
        lastBarTime = 0;
        heightByCategory = {};
        lastBarIndex = i;
      }
    }

    const paddingHeight = 4 * window.devicePixelRatio;
    const scale = (this._canvas.height - paddingHeight - this._minBarHeight) / maxBarTime;
    for (let i = 0; i < barTimes.length; ++i) {
      for (const categoryName in barHeightByCategory[i]) {
        barHeightByCategory[i][categoryName] *= (barTimes[i] * scale + this._minBarHeight) / barTimes[i];
      }
      this._renderBar(i, barHeightByCategory[i]);
    }
  }

  /**
   * @param {number} index
   * @param {!Object.<string, number>} heightByCategory
   */
  _renderBar(index, heightByCategory) {
    const categories = PaintProfilerView.categories();
    let currentHeight = 0;
    const x = this._barPaddingWidth + index * this._outerBarWidth;
    for (const categoryName in categories) {
      if (!heightByCategory[categoryName]) {
        continue;
      }
      currentHeight += heightByCategory[categoryName];
      const y = this._canvas.height - currentHeight;
      this._context.fillStyle = categories[categoryName].color;
      this._context.fillRect(x, y, this._innerBarWidth, heightByCategory[categoryName]);
    }
  }

  _onWindowChanged() {
    this.dispatchEventToListeners(Events.WindowChanged);
    this._updatePieChart();
    if (this._updateImageTimer) {
      return;
    }
    this._updateImageTimer = setTimeout(this._updateImage.bind(this), 100);
  }

  _updatePieChart() {
    const window = this.selectionWindow();
    if (!this._profiles || !this._profiles.length || !window) {
      return;
    }
    let totalTime = 0;
    const timeByCategory = {};
    for (let i = window.left; i < window.right; ++i) {
      const logEntry = this._log[i];
      const category = PaintProfilerView._categoryForLogItem(logEntry);
      timeByCategory[category.color] = timeByCategory[category.color] || 0;
      for (let j = 0; j < this._profiles.length; ++j) {
        const time = this._profiles[j][logEntry.commandIndex];
        totalTime += time;
        timeByCategory[category.color] += time;
      }
    }
    this._pieChart.setTotal(totalTime / this._profiles.length);
    for (const color in timeByCategory) {
      this._pieChart.addSlice(timeByCategory[color] / this._profiles.length, color);
    }
  }

  /**
   * @param {number} value
   * @return {string}
   */
  _formatPieChartTime(value) {
    return Number.millisToString(value * 1000, true);
  }

  /**
   * @return {?{left: number, right: number}}
   */
  selectionWindow() {
    if (!this._log) {
      return null;
    }

    const screenLeft = this._selectionWindow.windowLeft * this._canvas.width;
    const screenRight = this._selectionWindow.windowRight * this._canvas.width;
    const barLeft = Math.floor(screenLeft / this._outerBarWidth);
    const barRight = Math.floor((screenRight + this._innerBarWidth - this._barPaddingWidth / 2) / this._outerBarWidth);
    const stepLeft = Number.constrain(barLeft * this._samplesPerBar, 0, this._log.length - 1);
    const stepRight = Number.constrain(barRight * this._samplesPerBar, 0, this._log.length);

    return {left: stepLeft, right: stepRight};
  }

  _updateImage() {
    delete this._updateImageTimer;
    let left;
    let right;
    const window = this.selectionWindow();
    if (this._profiles && this._profiles.length && window) {
      left = this._log[window.left].commandIndex;
      right = this._log[window.right - 1].commandIndex;
    }
    const scale = this._pendingScale;
    this._snapshot.replay(scale, left, right).then(image => {
      if (!image) {
        return;
      }
      this._scale = scale;
      this._showImageCallback(image);
    });
  }

  _reset() {
    if (this._snapshot) {
      this._snapshot.release();
    }
    this._snapshot = null;
    this._profiles = null;
    this._selectionWindow.reset();
    this._selectionWindow.setEnabled(false);
  }
}

/** @enum {symbol} */
export const Events = {
  WindowChanged: Symbol('WindowChanged')
};

/**
 * @unrestricted
 */
export class PaintProfilerCommandLogView extends UI.ThrottledWidget {
  constructor() {
    super();
    this.setMinimumSize(100, 25);
    this.element.classList.add('overflow-auto');

    this._treeOutline = new UI.TreeOutlineInShadow();
    UI.ARIAUtils.setAccessibleName(this._treeOutline.contentElement, ls`Command Log`);
    this.element.appendChild(this._treeOutline.element);

    this._log = [];
  }

  /**
   * @param {!Array.<!SDK.PaintProfilerLogItem>} log
   */
  setCommandLog(log) {
    this._log = log;
    /** @type {!Map<!SDK.PaintProfilerLogItem>} */
    this._treeItemCache = new Map();
    this.updateWindow({left: 0, right: this._log.length});
  }

  /**
   * @param {!SDK.PaintProfilerLogItem} logItem
   */
  _appendLogItem(logItem) {
    let treeElement = this._treeItemCache.get(logItem);
    if (!treeElement) {
      treeElement = new LogTreeElement(this, logItem);
      this._treeItemCache.set(logItem, treeElement);
    } else if (treeElement.parent) {
      return;
    }
    this._treeOutline.appendChild(treeElement);
  }

  /**
   * @param {?{left: number, right: number}} selectionWindow
   */
  updateWindow(selectionWindow) {
    this._selectionWindow = selectionWindow;
    this.update();
  }

  /**
   * @override
   * @return {!Promise<*>}
   */
  doUpdate() {
    if (!this._selectionWindow || !this._log.length) {
      this._treeOutline.removeChildren();
      return Promise.resolve();
    }
    const root = this._treeOutline.rootElement();
    for (;;) {
      const child = root.firstChild();
      if (!child || child._logItem.commandIndex >= this._selectionWindow.left) {
        break;
      }
      root.removeChildAtIndex(0);
    }
    for (;;) {
      const child = root.lastChild();
      if (!child || child._logItem.commandIndex < this._selectionWindow.right) {
        break;
      }
      root.removeChildAtIndex(root.children().length - 1);
    }
    for (let i = this._selectionWindow.left, right = this._selectionWindow.right; i < right; ++i) {
      this._appendLogItem(this._log[i]);
    }
    return Promise.resolve();
  }
}

/**
 * @unrestricted
 */
export class LogTreeElement extends UI.TreeElement {
  /**
   * @param {!LayerViewer.PaintProfilerCommandLogView} ownerView
   * @param {!SDK.PaintProfilerLogItem} logItem
   */
  constructor(ownerView, logItem) {
    super('', !!logItem.params);
    this._logItem = logItem;
    this._ownerView = ownerView;
    this._filled = false;
  }

  /**
   * @override
   */
  onattach() {
    this._update();
  }

  /**
   * @override
   * @returns {!Promise}
   */
  async onpopulate() {
    for (const param in this._logItem.params) {
      LogPropertyTreeElement._appendLogPropertyItem(this, param, this._logItem.params[param]);
    }
  }

  /**
   * @param {*} param
   * @param {string} name
   * @return {string}
   */
  _paramToString(param, name) {
    if (typeof param !== 'object') {
      return typeof param === 'string' && param.length > 100 ? name : JSON.stringify(param);
    }
    let str = '';
    let keyCount = 0;
    for (const key in param) {
      if (++keyCount > 4 || typeof param[key] === 'object' ||
          (typeof param[key] === 'string' && param[key].length > 100)) {
        return name;
      }
      if (str) {
        str += ', ';
      }
      str += param[key];
    }
    return str;
  }

  /**
   * @param {?Object<string, *>} params
   * @return {string}
   */
  _paramsToString(params) {
    let str = '';
    for (const key in params) {
      if (str) {
        str += ', ';
      }
      str += this._paramToString(params[key], key);
    }
    return str;
  }

  _update() {
    const title = createDocumentFragment();
    title.createTextChild(this._logItem.method + '(' + this._paramsToString(this._logItem.params) + ')');
    this.title = title;
  }
}

/**
 * @unrestricted
 */
export class LogPropertyTreeElement extends UI.TreeElement {
  /**
   * @param {!{name: string, value}} property
   */
  constructor(property) {
    super();
    this._property = property;
  }

  /**
   * @param {!UI.TreeElement} element
   * @param {string} name
   * @param {*} value
   */
  static _appendLogPropertyItem(element, name, value) {
    const treeElement = new LogPropertyTreeElement({name: name, value: value});
    element.appendChild(treeElement);
    if (value && typeof value === 'object') {
      for (const property in value) {
        LogPropertyTreeElement._appendLogPropertyItem(treeElement, property, value[property]);
      }
    }
  }

  /**
   * @override
   */
  onattach() {
    const title = createDocumentFragment();
    const nameElement = title.createChild('span', 'name');
    nameElement.textContent = this._property.name;
    const separatorElement = title.createChild('span', 'separator');
    separatorElement.textContent = ': ';
    if (this._property.value === null || typeof this._property.value !== 'object') {
      const valueElement = title.createChild('span', 'value');
      valueElement.textContent = JSON.stringify(this._property.value);
      valueElement.classList.add('cm-js-' + (this._property.value === null ? 'null' : typeof this._property.value));
    }
    this.title = title;
  }
}

/**
 * @unrestricted
 */
export class PaintProfilerCategory {
  /**
   * @param {string} name
   * @param {string} title
   * @param {string} color
   */
  constructor(name, title, color) {
    this.name = name;
    this.title = title;
    this.color = color;
  }
}

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

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

/**
 * @constructor
 */
LayerViewer.PaintProfilerView = PaintProfilerView;

LayerViewer.PaintProfilerView.Events = Events;

/**
 * @constructor
 */
LayerViewer.PaintProfilerCommandLogView = PaintProfilerCommandLogView;

/**
 * @constructor
 */
LayerViewer.LogTreeElement = LogTreeElement;

/**
 * @constructor
 */
LayerViewer.LogPropertyTreeElement = LogPropertyTreeElement;

/**
 * @constructor
 */
LayerViewer.PaintProfilerCategory = PaintProfilerCategory;
