// Copyright (c) 2017 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.

export default class CoverageListView extends UI.VBox {
  /**
   * @param {function(!Coverage.URLCoverageInfo):boolean} filterCallback
   */
  constructor(filterCallback) {
    super(true);
    /** @type {!Map<!Coverage.URLCoverageInfo, !Coverage.CoverageListView.GridNode>} */
    this._nodeForCoverageInfo = new Map();
    this._filterCallback = filterCallback;
    /** @type {?RegExp} */
    this._highlightRegExp = null;
    this.registerRequiredCSS('coverage/coverageListView.css');
    const columns = [
      {id: 'url', title: Common.UIString('URL'), width: '250px', fixedWidth: false, sortable: true},
      {id: 'type', title: Common.UIString('Type'), width: '45px', fixedWidth: true, sortable: true}, {
        id: 'size',
        title: Common.UIString('Total Bytes'),
        width: '60px',
        fixedWidth: true,
        sortable: true,
        align: DataGrid.DataGrid.Align.Right
      },
      {
        id: 'unusedSize',
        title: Common.UIString('Unused Bytes'),
        width: '100px',
        fixedWidth: true,
        sortable: true,
        align: DataGrid.DataGrid.Align.Right,
        sort: DataGrid.DataGrid.Order.Descending
      },
      {id: 'bars', title: ls`Usage Visualization`, width: '250px', fixedWidth: false, sortable: true}
    ];
    this._dataGrid = new DataGrid.SortableDataGrid(columns);
    this._dataGrid.setResizeMethod(DataGrid.DataGrid.ResizeMethod.Last);
    this._dataGrid.element.classList.add('flex-auto');
    this._dataGrid.element.addEventListener('keydown', this._onKeyDown.bind(this), false);
    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.OpenedNode, this._onOpenedNode, this);
    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._sortingChanged, this);

    const dataGridWidget = this._dataGrid.asWidget();
    dataGridWidget.show(this.contentElement);
  }

  /**
   * @param {!Array<!Coverage.URLCoverageInfo>} coverageInfo
   */
  update(coverageInfo) {
    let hadUpdates = false;
    const maxSize = coverageInfo.reduce((acc, entry) => Math.max(acc, entry.size()), 0);
    const rootNode = this._dataGrid.rootNode();
    for (const entry of coverageInfo) {
      let node = this._nodeForCoverageInfo.get(entry);
      if (node) {
        if (this._filterCallback(node._coverageInfo)) {
          hadUpdates = node._refreshIfNeeded(maxSize) || hadUpdates;
        }
        continue;
      }
      node = new GridNode(entry, maxSize);
      this._nodeForCoverageInfo.set(entry, node);
      if (this._filterCallback(node._coverageInfo)) {
        rootNode.appendChild(node);
        hadUpdates = true;
      }
    }
    if (hadUpdates) {
      this._sortingChanged();
    }
  }

  reset() {
    this._nodeForCoverageInfo.clear();
    this._dataGrid.rootNode().removeChildren();
  }

  /**
   * @param {?RegExp} highlightRegExp
   */
  updateFilterAndHighlight(highlightRegExp) {
    this._highlightRegExp = highlightRegExp;
    let hadTreeUpdates = false;
    for (const node of this._nodeForCoverageInfo.values()) {
      const shouldBeVisible = this._filterCallback(node._coverageInfo);
      const isVisible = !!node.parent;
      if (shouldBeVisible) {
        node._setHighlight(this._highlightRegExp);
      }
      if (shouldBeVisible === isVisible) {
        continue;
      }
      hadTreeUpdates = true;
      if (!shouldBeVisible) {
        node.remove();
      } else {
        this._dataGrid.rootNode().appendChild(node);
      }
    }
    if (hadTreeUpdates) {
      this._sortingChanged();
    }
  }

  selectByUrl(url) {
    for (const [info, node] of this._nodeForCoverageInfo.entries()) {
      if (info.url() === url) {
        node.revealAndSelect();
        break;
      }
    }
  }

  _onOpenedNode() {
    this._revealSourceForSelectedNode();
  }

  /**
   * @param {!Event} event
   */
  _onKeyDown(event) {
    if (!isEnterKey(event)) {
      return;
    }
    event.consume(true);
    this._revealSourceForSelectedNode();
  }

  async _revealSourceForSelectedNode() {
    const node = this._dataGrid.selectedNode;
    if (!node) {
      return;
    }
    const coverageInfo = /** @type {!Coverage.CoverageListView.GridNode} */ (node)._coverageInfo;
    let sourceCode = Workspace.workspace.uiSourceCodeForURL(coverageInfo.url());
    if (!sourceCode) {
      return;
    }

    sourceCode = await sourceCode.getFormatted();

    if (this._dataGrid.selectedNode !== node) {
      return;
    }
    Common.Revealer.reveal(sourceCode);
  }

  _sortingChanged() {
    const columnId = this._dataGrid.sortColumnId();
    if (!columnId) {
      return;
    }
    let sortFunction;
    switch (columnId) {
      case 'url':
        sortFunction = compareURL;
        break;
      case 'type':
        sortFunction = compareType;
        break;
      case 'size':
        sortFunction = compareNumericField.bind(null, 'size');
        break;
      case 'bars':
      case 'unusedSize':
        sortFunction = compareNumericField.bind(null, 'unusedSize');
        break;
      default:
        console.assert(false, 'Unknown sort field: ' + columnId);
        return;
    }

    this._dataGrid.sortNodes(sortFunction, !this._dataGrid.isSortOrderAscending());

    /**
     * @param {!DataGrid.DataGridNode} a
     * @param {!DataGrid.DataGridNode} b
     * @return {number}
     */
    function compareURL(a, b) {
      const nodeA = /** @type {!Coverage.CoverageListView.GridNode} */ (a);
      const nodeB = /** @type {!Coverage.CoverageListView.GridNode} */ (b);

      return nodeA._url.localeCompare(nodeB._url);
    }

    /**
     * @param {string} fieldName
     * @param {!DataGrid.DataGridNode} a
     * @param {!DataGrid.DataGridNode} b
     * @return {number}
     */
    function compareNumericField(fieldName, a, b) {
      const nodeA = /** @type {!Coverage.CoverageListView.GridNode} */ (a);
      const nodeB = /** @type {!Coverage.CoverageListView.GridNode} */ (b);

      return nodeA._coverageInfo[fieldName]() - nodeB._coverageInfo[fieldName]() || compareURL(a, b);
    }

    /**
     * @param {!DataGrid.DataGridNode} a
     * @param {!DataGrid.DataGridNode} b
     * @return {number}
     */
    function compareType(a, b) {
      const nodeA = /** @type {!Coverage.CoverageListView.GridNode} */ (a);
      const nodeB = /** @type {!Coverage.CoverageListView.GridNode} */ (b);
      const typeA = Coverage.CoverageListView._typeToString(nodeA._coverageInfo.type());
      const typeB = Coverage.CoverageListView._typeToString(nodeB._coverageInfo.type());
      return typeA.localeCompare(typeB) || compareURL(a, b);
    }
  }

  /**
   * @param {!Coverage.CoverageType} type
   */
  static _typeToString(type) {
    const types = [];
    if (type & Coverage.CoverageType.CSS) {
      types.push(Common.UIString('CSS'));
    }
    if (type & Coverage.CoverageType.JavaScriptPerFunction) {
      types.push(Common.UIString('JS (per function)'));
    } else if (type & Coverage.CoverageType.JavaScript) {
      types.push(Common.UIString('JS (per block)'));
    }
    return types.join('+');
  }
}

export class GridNode extends DataGrid.SortableDataGridNode {
  /**
   * @param {!Coverage.URLCoverageInfo} coverageInfo
   * @param {number} maxSize
   */
  constructor(coverageInfo, maxSize) {
    super();
    this._coverageInfo = coverageInfo;
    /** @type {number|undefined} */
    this._lastUsedSize;
    this._url = coverageInfo.url();
    this._maxSize = maxSize;
    this._highlightDOMChanges = [];
    /** @type {?RegExp} */
    this._highlightRegExp = null;
  }

  /**
   * @param {?RegExp} highlightRegExp
   */
  _setHighlight(highlightRegExp) {
    if (this._highlightRegExp === highlightRegExp) {
      return;
    }
    this._highlightRegExp = highlightRegExp;
    this.refresh();
  }

  /**
   * @param {number} maxSize
   * @return {boolean}
   */
  _refreshIfNeeded(maxSize) {
    if (this._lastUsedSize === this._coverageInfo.usedSize() && maxSize === this._maxSize) {
      return false;
    }
    this._lastUsedSize = this._coverageInfo.usedSize();
    this._maxSize = maxSize;
    this.refresh();
    return true;
  }

  /**
   * @override
   * @param {string} columnId
   * @return {!Element}
   */
  createCell(columnId) {
    const cell = this.createTD(columnId);
    switch (columnId) {
      case 'url':
        cell.title = this._url;
        const outer = cell.createChild('div', 'url-outer');
        const prefix = outer.createChild('div', 'url-prefix');
        const suffix = outer.createChild('div', 'url-suffix');
        const splitURL = /^(.*)(\/[^/]*)$/.exec(this._url);
        prefix.textContent = splitURL ? splitURL[1] : this._url;
        suffix.textContent = splitURL ? splitURL[2] : '';
        if (this._highlightRegExp) {
          this._highlight(outer, this._url);
        }
        break;
      case 'type':
        cell.textContent = Coverage.CoverageListView._typeToString(this._coverageInfo.type());
        if (this._coverageInfo.type() & Coverage.CoverageType.JavaScriptPerFunction) {
          cell.title = ls
          `JS coverage with per function granularity: Once a function was executed, the whole function is marked as covered.`;
        } else if (this._coverageInfo.type() & Coverage.CoverageType.JavaScript) {
          cell.title = ls
          `JS coverage with per block granularity: Once a block of JavaScript was executed, that block is marked as covered.`;
        }
        break;
      case 'size':
        const sizeSpan = cell.createChild('span');
        sizeSpan.textContent = Number.withThousandsSeparator(this._coverageInfo.size() || 0);
        UI.ARIAUtils.markAsHidden(sizeSpan);
        UI.ARIAUtils.setAccessibleName(cell, ls`${this._coverageInfo.size() || 0} bytes`);
        break;
      case 'unusedSize':
        const unusedSize = this._coverageInfo.unusedSize() || 0;
        const unusedSizeSpan = cell.createChild('span');
        const unusedPercentsSpan = cell.createChild('span', 'percent-value');
        unusedSizeSpan.textContent = Number.withThousandsSeparator(unusedSize);
        const unusedPercentFormatted = ls`${this._percentageString(this._coverageInfo.unusedPercentage())} %`;
        unusedPercentsSpan.textContent = unusedPercentFormatted;
        UI.ARIAUtils.markAsHidden(unusedPercentsSpan);
        UI.ARIAUtils.markAsHidden(unusedSizeSpan);
        UI.ARIAUtils.setAccessibleName(cell, ls`${unusedSize} bytes, ${unusedPercentFormatted}`);
        break;
      case 'bars':
        const barContainer = cell.createChild('div', 'bar-container');
        const unusedPercent = this._percentageString(this._coverageInfo.unusedPercentage());
        const usedPercent = this._percentageString(this._coverageInfo.usedPercentage());
        if (this._coverageInfo.unusedSize() > 0) {
          const unusedSizeBar = barContainer.createChild('div', 'bar bar-unused-size');
          unusedSizeBar.style.width = ((this._coverageInfo.unusedSize() / this._maxSize) * 100 || 0) + '%';
          if (this._coverageInfo.type() & Coverage.CoverageType.JavaScriptPerFunction) {
            unusedSizeBar.title = ls`${this._coverageInfo.unusedSize()} bytes (${
                unusedPercent} %) belong to functions that have not (yet) been executed.`;
          } else if (this._coverageInfo.type() & Coverage.CoverageType.JavaScript) {
            unusedSizeBar.title = ls`${this._coverageInfo.unusedSize()} bytes (${
                unusedPercent} %) belong to blocks of JavaScript that have not (yet) been executed.`;
          }
        }
        if (this._coverageInfo.usedSize() > 0) {
          const usedSizeBar = barContainer.createChild('div', 'bar bar-used-size');
          usedSizeBar.style.width = ((this._coverageInfo.usedSize() / this._maxSize) * 100 || 0) + '%';
          if (this._coverageInfo.type() & Coverage.CoverageType.JavaScriptPerFunction) {
            usedSizeBar.title = ls`${this._coverageInfo.usedSize()} bytes (${
                usedPercent} %) belong to functions that have executed at least once.`;
          } else if (this._coverageInfo.type() & Coverage.CoverageType.JavaScript) {
            usedSizeBar.title = ls`${this._coverageInfo.usedSize()} bytes (${
                usedPercent} %) belong to blocks of JavaScript that have executed at least once.`;
          }
        }
        UI.ARIAUtils.setAccessibleName(
            barContainer, ls`${unusedPercent} % of file unused, ${usedPercent} % of file used`);
    }
    return cell;
  }

  /**
   * @param {number} value
   * @return {string}
   */
  _percentageString(value) {
    return value.toFixed(1);
  }

  /**
   * @param {!Element} element
   * @param {string} textContent
   */
  _highlight(element, textContent) {
    const matches = this._highlightRegExp.exec(textContent);
    if (!matches || !matches.length) {
      return;
    }
    const range = new TextUtils.SourceRange(matches.index, matches[0].length);
    UI.highlightRangesWithStyleClass(element, [range], 'filter-highlight');
  }
}

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

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

/**
 * @constructor
 */
Coverage.CoverageListView = CoverageListView;

/**
 * @constructor
 */
Coverage.CoverageListView.GridNode = GridNode;
