// Copyright 2018 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 ProtocolMonitorImpl extends UI.VBox {
  constructor() {
    super(true);
    this._nodes = [];
    this._started = false;
    this._startTime = 0;
    this._nodeForId = {};
    this._filter = node => true;
    this._columns = [
      {id: 'method', title: ls`Method`, visible: true, sortable: true, weight: 60},
      {id: 'direction', title: ls`Direction`, visible: false, sortable: true, hideable: true, weight: 30},
      {id: 'request', title: ls`Request`, visible: true, hideable: true, weight: 60},
      {id: 'response', title: ls`Response`, visible: true, hideable: true, weight: 60},
      {id: 'timestamp', title: ls`Timestamp`, visible: false, sortable: true, hideable: true, weight: 30},
      {id: 'target', title: ls`Target`, visible: false, sortable: true, hideable: true, weight: 30}
    ];

    this.registerRequiredCSS('protocol_monitor/protocolMonitor.css');
    const topToolbar = new UI.Toolbar('protocol-monitor-toolbar', this.contentElement);
    const recordButton = new UI.ToolbarToggle(ls`Record`, 'largeicon-start-recording', 'largeicon-stop-recording');
    recordButton.addEventListener(UI.ToolbarButton.Events.Click, () => {
      recordButton.setToggled(!recordButton.toggled());
      this._setRecording(recordButton.toggled());
    });
    recordButton.setToggleWithRedColor(true);
    topToolbar.appendToolbarItem(recordButton);
    recordButton.setToggled(true);

    const clearButton = new UI.ToolbarButton(ls`Clear all`, 'largeicon-clear');
    clearButton.addEventListener(UI.ToolbarButton.Events.Click, () => {
      this._dataGrid.rootNode().removeChildren();
      this._nodes = [];
      this._nodeForId = {};
    });
    topToolbar.appendToolbarItem(clearButton);

    const split = new UI.SplitWidget(true, true, 'protocol-monitor-panel-split', 250);
    split.show(this.contentElement);
    this._dataGrid = new DataGrid.SortableDataGrid(this._columns);
    this._dataGrid.element.style.flex = '1';
    this._infoWidget = new ProtocolMonitor.ProtocolMonitor.InfoWidget();
    split.setMainWidget(this._dataGrid.asWidget());
    split.setSidebarWidget(this._infoWidget);
    this._dataGrid.addEventListener(
        DataGrid.DataGrid.Events.SelectedNode, event => this._infoWidget.render(event.data.data));
    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.DeselectedNode, event => this._infoWidget.render(null));
    this._dataGrid.setHeaderContextMenuCallback(this._innerHeaderContextMenu.bind(this));
    this._dataGrid.setRowContextMenuCallback(this._innerRowContextMenu.bind(this));


    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._sortDataGrid.bind(this));
    this._dataGrid.setStickToBottom(true);
    this._dataGrid.sortNodes(DataGrid.SortableDataGrid.NumericComparator.bind(null, 'timestamp'), false);
    this._updateColumnVisibility();

    const keys = ['method', 'request', 'response', 'direction'];
    this._filterParser = new TextUtils.FilterParser(keys);
    this._suggestionBuilder = new UI.FilterSuggestionBuilder(keys);

    this._textFilterUI = new UI.ToolbarInput(
        ls`Filter`, '', 1, .2, '', this._suggestionBuilder.completions.bind(this._suggestionBuilder));
    this._textFilterUI.addEventListener(UI.ToolbarInput.Event.TextChanged, event => {
      const query = /** @type {string} */ (event.data);
      const filters = this._filterParser.parse(query);
      this._filter = node => {
        for (const {key, text, negative} of filters) {
          if (!text) {
            continue;
          }
          const data = key ? node.data[key] : node.data;
          if (!data) {
            continue;
          }
          const found = JSON.stringify(data).toLowerCase().indexOf(text.toLowerCase()) !== -1;
          if (found === negative) {
            return false;
          }
        }
        return true;
      };
      this._filterNodes();
    });
    topToolbar.appendToolbarItem(this._textFilterUI);
  }

  _filterNodes() {
    for (const node of this._nodes) {
      if (this._filter(node)) {
        if (!node.parent) {
          this._dataGrid.insertChild(node);
        }
      } else {
        node.remove();
      }
    }
  }

  /**
   * @param {!UI.ContextSubMenu} contextMenu
   */
  _innerHeaderContextMenu(contextMenu) {
    const columnConfigs = this._columns.filter(columnConfig => columnConfig.hideable);
    for (const columnConfig of columnConfigs) {
      contextMenu.headerSection().appendCheckboxItem(
          columnConfig.title, this._toggleColumnVisibility.bind(this, columnConfig), columnConfig.visible);
    }
  }

  /**
   * @param {!UI.ContextMenu} contextMenu
   * @param {!ProtocolMonitor.ProtocolMonitor.ProtocolNode} node
   */
  _innerRowContextMenu(contextMenu, node) {
    contextMenu.defaultSection().appendItem(ls`Filter`, () => {
      this._textFilterUI.setValue(`method:${node.data.method}`, true);
    });
    contextMenu.defaultSection().appendItem(ls`Documentation`, () => {
      const [domain, method] = node.data.method.split('.');
      const type = node.data.direction === 'sent' ? 'method' : 'event';
      Host.InspectorFrontendHost.openInNewTab(
          `https://chromedevtools.github.io/devtools-protocol/tot/${domain}#${type}-${method}`);
    });
  }

  /**
   * @param {!Object} columnConfig
   */
  _toggleColumnVisibility(columnConfig) {
    columnConfig.visible = !columnConfig.visible;
    this._updateColumnVisibility();
  }

  _updateColumnVisibility() {
    const visibleColumns = /** @type {!Object.<string, boolean>} */ ({});
    for (const columnConfig of this._columns) {
      visibleColumns[columnConfig.id] = columnConfig.visible;
    }
    this._dataGrid.setColumnsVisiblity(visibleColumns);
  }

  _sortDataGrid() {
    const sortColumnId = this._dataGrid.sortColumnId();
    if (!sortColumnId) {
      return;
    }

    let columnIsNumeric = true;
    switch (sortColumnId) {
      case 'method':
      case 'direction':
        columnIsNumeric = false;
        break;
    }


    const comparator =
        columnIsNumeric ? DataGrid.SortableDataGrid.NumericComparator : DataGrid.SortableDataGrid.StringComparator;
    this._dataGrid.sortNodes(comparator.bind(null, sortColumnId), !this._dataGrid.isSortOrderAscending());
  }

  /**
   * @override
   */
  wasShown() {
    if (this._started) {
      return;
    }
    this._started = true;
    this._startTime = Date.now();
    this._setRecording(true);
  }

  /**
   * @param {boolean} recording
   */
  _setRecording(recording) {
    if (recording) {
      Protocol.test.onMessageSent = this._messageSent.bind(this);
      Protocol.test.onMessageReceived = this._messageRecieved.bind(this);
    } else {
      Protocol.test.onMessageSent = null;
      Protocol.test.onMessageReceived = null;
    }
  }

  /**
   * @param {?SDK.Target} target
   * @return {string}
   */
  _targetToString(target) {
    if (!target) {
      return '';
    }
    return target.decorateLabel(`${target.name()} ${target === SDK.targetManager.mainTarget() ? '' : target.id()}`);
  }

  /**
   * @param {!Object} message
   * @param {?Protocol.TargetBase} target
   */
  _messageRecieved(message, target) {
    if ('id' in message) {
      const node = this._nodeForId[message.id];
      if (!node) {
        return;
      }
      node.data.response = message.result || message.error;
      node.hasError = !!message.error;
      node.refresh();
      if (this._dataGrid.selectedNode === node) {
        this._infoWidget.render(node.data);
      }
      return;
    }

    const sdkTarget = /** @type {?SDK.Target} */ (target);
    const node = new ProtocolMonitor.ProtocolMonitor.ProtocolNode({
      method: message.method,
      direction: 'recieved',
      response: message.params,
      timestamp: Date.now() - this._startTime,
      request: '',
      target: this._targetToString(sdkTarget)
    });
    this._nodes.push(node);
    if (this._filter(node)) {
      this._dataGrid.insertChild(node);
    }
  }

  /**
   * @param {{domain: string, method: string, params: !Object, id: number}} message
   * @param {?Protocol.TargetBase} target
   */
  _messageSent(message, target) {
    const sdkTarget = /** @type {?SDK.Target} */ (target);
    const node = new ProtocolMonitor.ProtocolMonitor.ProtocolNode({
      method: message.method,
      direction: 'sent',
      request: message.params,
      timestamp: Date.now() - this._startTime,
      response: '(pending)',
      id: message.id,
      target: this._targetToString(sdkTarget)
    });
    this._nodeForId[message.id] = node;
    this._nodes.push(node);
    if (this._filter(node)) {
      this._dataGrid.insertChild(node);
    }
  }
}

export class ProtocolNode extends DataGrid.SortableDataGridNode {
  constructor(data) {
    super(data);
    this.hasError = false;
  }

  /**
   * @override
   * @param {string} columnId
   * @return {!Element}
   */
  createCell(columnId) {
    switch (columnId) {
      case 'response':
        if (!this.data[columnId] && this.data.direction === 'send') {
          const cell = this.createTD(columnId);
          cell.textContent = '(pending)';
          return cell;
        }
      // fall through
      case 'request': {
        const cell = this.createTD(columnId);
        const obj = SDK.RemoteObject.fromLocalObject(this.data[columnId]);
        cell.textContent = obj.description.trimEndWithMaxLength(50);
        cell.classList.add('source-code');
        return cell;
      }

      case 'timestamp': {
        const cell = this.createTD(columnId);
        cell.textContent = ls`${this.data[columnId]} ms`;
        return cell;
      }
    }
    return super.createCell(columnId);
  }

  /**
   * @override
   */
  element() {
    const element = super.element();
    element.classList.toggle('protocol-message-sent', this.data.direction === 'sent');
    element.classList.toggle('protocol-message-recieved', this.data.direction !== 'sent');
    element.classList.toggle('error', this.hasError);
    return element;
  }
}

export class InfoWidget extends UI.VBox {
  constructor() {
    super();
    this._tabbedPane = new UI.TabbedPane();
    this._tabbedPane.appendTab('request', 'Request', new UI.Widget());
    this._tabbedPane.appendTab('response', 'Response', new UI.Widget());
    this._tabbedPane.show(this.contentElement);
    this._tabbedPane.selectTab('response');
    this.render(null);
  }

  /**
   * @param {?{method: string, direction: string, request: ?Object, response: ?Object, timestamp: number}} data
   */
  render(data) {
    const requestEnabled = data && data.direction === 'sent';
    this._tabbedPane.setTabEnabled('request', !!requestEnabled);
    if (!data) {
      this._tabbedPane.changeTabView('request', new UI.EmptyWidget(ls`No message selected`));
      this._tabbedPane.changeTabView('response', new UI.EmptyWidget(ls`No message selected`));
      return;
    }
    if (!requestEnabled) {
      this._tabbedPane.selectTab('response');
    }

    this._tabbedPane.changeTabView('request', SourceFrame.JSONView.createViewSync(data.request));
    this._tabbedPane.changeTabView('response', SourceFrame.JSONView.createViewSync(data.response));
  }
}

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

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

/**
 * @constructor
 */
ProtocolMonitor.ProtocolMonitor = ProtocolMonitorImpl;

/**
 * @constructor
 */
ProtocolMonitor.ProtocolMonitor.InfoWidget = InfoWidget;

/**
 * @constructor
 */
ProtocolMonitor.ProtocolMonitor.ProtocolNode = ProtocolNode;
