// 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.

Resources.ServiceWorkerCacheView = class extends UI.SimpleView {
  /**
   * @param {!SDK.ServiceWorkerCacheModel} model
   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
   */
  constructor(model, cache) {
    super(Common.UIString('Cache'));
    this.registerRequiredCSS('resources/serviceWorkerCacheViews.css');

    this._model = model;
    this._entriesForTest = null;

    this.element.classList.add('service-worker-cache-data-view');
    this.element.classList.add('storage-view');

    const editorToolbar = new UI.Toolbar('data-view-toolbar', this.element);
    this._splitWidget = new UI.SplitWidget(false, false);
    this._splitWidget.show(this.element);

    this._previewPanel = new UI.VBox();
    const resizer = this._previewPanel.element.createChild('div', 'cache-preview-panel-resizer');
    this._splitWidget.setMainWidget(this._previewPanel);
    this._splitWidget.installResizer(resizer);

    /** @type {?UI.Widget} */
    this._preview = null;

    this._cache = cache;
    /** @type {?DataGrid.DataGrid} */
    this._dataGrid = null;
    /** @type {?number} */
    this._lastPageSize = null;
    /** @type {?number} */
    this._lastSkipCount = null;
    this._refreshThrottler = new Common.Throttler(300);

    this._pageBackButton = new UI.ToolbarButton(Common.UIString('Show previous page'), 'largeicon-play-back');
    this._pageBackButton.addEventListener(UI.ToolbarButton.Events.Click, this._pageBackButtonClicked, this);
    editorToolbar.appendToolbarItem(this._pageBackButton);

    this._pageForwardButton = new UI.ToolbarButton(Common.UIString('Show next page'), 'largeicon-play');
    this._pageForwardButton.setEnabled(false);
    this._pageForwardButton.addEventListener(UI.ToolbarButton.Events.Click, this._pageForwardButtonClicked, this);
    editorToolbar.appendToolbarItem(this._pageForwardButton);

    this._refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
    this._refreshButton.addEventListener(UI.ToolbarButton.Events.Click, this._refreshButtonClicked, this);
    editorToolbar.appendToolbarItem(this._refreshButton);

    this._deleteSelectedButton = new UI.ToolbarButton(Common.UIString('Delete Selected'), 'largeicon-delete');
    this._deleteSelectedButton.addEventListener(UI.ToolbarButton.Events.Click, () => this._deleteButtonClicked(null));
    editorToolbar.appendToolbarItem(this._deleteSelectedButton);

    this._pageSize = 50;
    this._skipCount = 0;

    this.update(cache);
  }

  /**
   * @override
   */
  wasShown() {
    this._model.addEventListener(
        SDK.ServiceWorkerCacheModel.Events.CacheStorageContentUpdated, this._cacheContentUpdated, this);
    this._updateData(true);
  }

  /**
   * @override
   */
  willHide() {
    this._model.removeEventListener(
        SDK.ServiceWorkerCacheModel.Events.CacheStorageContentUpdated, this._cacheContentUpdated, this);
  }

  /**
   * @param {?UI.Widget} preview
   */
  _showPreview(preview) {
    if (this._preview === preview)
      return;
    if (this._preview)
      this._preview.detach();
    if (!preview)
      preview = new UI.EmptyWidget(Common.UIString('Select a cache entry above to preview'));
    this._preview = preview;
    this._preview.show(this._previewPanel.element);
  }

  /**
   * @return {!DataGrid.DataGrid}
   */
  _createDataGrid() {
    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([
      {id: 'path', title: Common.UIString('Path'), weight: 4, sortable: true},
      {id: 'contentType', title: Common.UIString('Content-Type'), weight: 1, sortable: true}, {
        id: 'contentLength',
        title: Common.UIString('Content-Length'),
        weight: 1,
        align: DataGrid.DataGrid.Align.Right,
        sortable: true
      },
      {
        id: 'responseTime',
        title: Common.UIString('Time Cached'),
        width: '12em',
        weight: 1,
        align: DataGrid.DataGrid.Align.Right,
        sortable: true
      }
    ]);
    const dataGrid = new DataGrid.DataGrid(
        columns, undefined, this._deleteButtonClicked.bind(this), this._updateData.bind(this, true));

    dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged, this._sortingChanged, this);

    dataGrid.addEventListener(
        DataGrid.DataGrid.Events.SelectedNode, event => this._previewCachedResponse(event.data.data), this);
    dataGrid.setStriped(true);
    return dataGrid;
  }

  _sortingChanged() {
    if (!this._dataGrid)
      return;

    const accending = this._dataGrid.isSortOrderAscending();
    const columnId = this._dataGrid.sortColumnId();
    let comparator;
    if (columnId === 'path')
      comparator = (a, b) => a._path.localeCompare(b._path);
    else if (columnId === 'contentType')
      comparator = (a, b) => a.data.mimeType.localeCompare(b.data.mimeType);
    else if (columnId === 'contentLength')
      comparator = (a, b) => a.data.resourceSize - b.data.resourceSize;
    else if (columnId === 'responseTime')
      comparator = (a, b) => a.data.endTime - b.data.endTime;

    const children = this._dataGrid.rootNode().children.slice();
    this._dataGrid.rootNode().removeChildren();
    children.sort((a, b) => {
      const result = comparator(a, b);
      return accending ? result : -result;
    });
    children.forEach(child => this._dataGrid.rootNode().appendChild(child));
  }

  /**
   * @param {!Common.Event} event
   */
  _pageBackButtonClicked(event) {
    this._skipCount = Math.max(0, this._skipCount - this._pageSize);
    this._updateData(false);
  }

  /**
   * @param {!Common.Event} event
   */
  _pageForwardButtonClicked(event) {
    this._skipCount = this._skipCount + this._pageSize;
    this._updateData(false);
  }

  /**
   * @param {?DataGrid.DataGridNode} node
   */
  async _deleteButtonClicked(node) {
    if (!node) {
      node = this._dataGrid && this._dataGrid.selectedNode;
      if (!node)
        return;
    }
    await this._model.deleteCacheEntry(this._cache, /** @type {string} */ (node.data.url()));
    node.remove();
  }

  /**
   * @param {!SDK.ServiceWorkerCacheModel.Cache} cache
   */
  update(cache) {
    this._cache = cache;

    if (this._dataGrid)
      this._dataGrid.asWidget().detach();
    this._dataGrid = this._createDataGrid();
    this._splitWidget.setSidebarWidget(this._dataGrid.asWidget());
    this._skipCount = 0;
    this._updateData(true);
  }

  /**
   * @param {number} skipCount
   * @param {!Array<!Protocol.CacheStorage.DataEntry>} entries
   * @param {boolean} hasMore
   * @this {Resources.ServiceWorkerCacheView}
   */
  _updateDataCallback(skipCount, entries, hasMore) {
    const selected = this._dataGrid.selectedNode && this._dataGrid.selectedNode.data.url();
    this._refreshButton.setEnabled(true);
    this._entriesForTest = entries;

    /** @type {!Map<string, !DataGrid.DataGridNode>} */
    const oldEntries = new Map();
    const rootNode = this._dataGrid.rootNode();
    for (const node of rootNode.children)
      oldEntries.set(node.data.url, node);
    rootNode.removeChildren();
    let selectedNode = null;
    for (const entry of entries) {
      let node = oldEntries.get(entry.requestURL);
      if (!node || node.data.responseTime !== entry.responseTime) {
        node = new Resources.ServiceWorkerCacheView.DataGridNode(this._createRequest(entry));
        node.selectable = true;
      }
      rootNode.appendChild(node);
      if (entry.requestURL === selected)
        selectedNode = node;
    }
    this._pageBackButton.setEnabled(!!skipCount);
    this._pageForwardButton.setEnabled(hasMore);
    if (!selectedNode)
      this._showPreview(null);
    else
      selectedNode.revealAndSelect();
    this._updatedForTest();
  }

  /**
   * @param {boolean} force
   */
  _updateData(force) {
    const pageSize = this._pageSize;
    let skipCount = this._skipCount;

    if (!force && this._lastPageSize === pageSize && this._lastSkipCount === skipCount)
      return;
    this._refreshButton.setEnabled(false);
    if (this._lastPageSize !== pageSize) {
      skipCount = 0;
      this._skipCount = 0;
    }
    this._lastPageSize = pageSize;
    this._lastSkipCount = skipCount;
    this._model.loadCacheData(this._cache, skipCount, pageSize, this._updateDataCallback.bind(this, skipCount));
  }

  /**
   * @param {!Common.Event} event
   */
  _refreshButtonClicked(event) {
    this._updateData(true);
  }

  /**
   * @param {!Common.Event} event
   */
  _cacheContentUpdated(event) {
    const nameAndOrigin = event.data;
    if (this._cache.securityOrigin !== nameAndOrigin.origin || this._cache.cacheName !== nameAndOrigin.cacheName)
      return;
    this._refreshThrottler.schedule(() => Promise.resolve(this._updateData(true)), true);
  }

  /**
   * @param {!SDK.NetworkRequest} request
   */
  async _previewCachedResponse(request) {
    let preview = request[Resources.ServiceWorkerCacheView._previewSymbol];
    if (!preview) {
      preview = new Resources.ServiceWorkerCacheView.RequestView(request);
      request[Resources.ServiceWorkerCacheView._previewSymbol] = preview;
    }

    // It is possible that table selection changes before the preview opens.
    if (request === this._dataGrid.selectedNode.data)
      this._showPreview(preview);
  }

  /**
   * @param {!Protocol.CacheStorage.DataEntry} entry
   * @return {!SDK.NetworkRequest}
   */
  _createRequest(entry) {
    const request = new SDK.NetworkRequest('cache-storage-' + entry.requestURL, entry.requestURL, '', '', '', null);
    request.requestMethod = entry.requestMethod;
    request.setRequestHeaders(entry.requestHeaders);
    request.statusCode = entry.responseStatus;
    request.statusText = entry.responseStatusText;
    request.protocol = new Common.ParsedURL(entry.requestURL).scheme;
    request.responseHeaders = entry.responseHeaders;
    request.setRequestHeadersText('');
    request.endTime = entry.responseTime;

    let header = entry.responseHeaders.find(header => header.name.toLowerCase() === 'content-type');
    const contentType = header ? header.value : 'text/plain';
    request.mimeType = contentType;

    header = entry.responseHeaders.find(header => header.name.toLowerCase() === 'content-length');
    request.resourceSize = (header && header.value) | 0;

    let resourceType = Common.ResourceType.fromMimeType(contentType);
    if (!resourceType)
      resourceType = Common.ResourceType.fromURL(entry.requestURL) || Common.resourceTypes.Other;
    request.setResourceType(resourceType);
    request.setContentDataProvider(this._requestContent.bind(this, request));
    return request;
  }

  /**
   * @param {!SDK.NetworkRequest} request
   * @return {!Promise<!SDK.NetworkRequest.ContentData>}
   */
  async _requestContent(request) {
    const isText = request.resourceType().isTextType();
    const contentData = {error: null, content: null, encoded: !isText};
    const response = await this._cache.requestCachedResponse(request.url());
    if (response)
      contentData.content = isText ? window.atob(response.body) : response.body;
    return contentData;
  }

  _updatedForTest() {
  }
};

Resources.ServiceWorkerCacheView._previewSymbol = Symbol('preview');

Resources.ServiceWorkerCacheView._RESPONSE_CACHE_SIZE = 10;

Resources.ServiceWorkerCacheView.DataGridNode = class extends DataGrid.DataGridNode {
  /**
   * @param {!SDK.NetworkRequest} request
   */
  constructor(request) {
    super(request);
    this._path = Common.ParsedURL.extractPath(request.url());
    if (!this._path)
      this._path = request.url();
    if (this._path.length > 1 && this._path.startsWith('/'))
      this._path = this._path.substring(1);
    this._request = request;
  }

  /**
   * @override
   * @param {string} columnId
   * @return {!Element}
   */
  createCell(columnId) {
    const cell = this.createTD(columnId);
    let value;
    if (columnId === 'path')
      value = this._path;
    else if (columnId === 'contentType')
      value = this._request.mimeType;
    else if (columnId === 'contentLength')
      value = (this._request.resourceSize | 0).toLocaleString('en-US');
    else if (columnId === 'responseTime')
      value = new Date(this._request.endTime * 1000).toLocaleString();
    DataGrid.DataGrid.setElementText(cell, value || '', true);
    return cell;
  }
};

Resources.ServiceWorkerCacheView.RequestView = class extends UI.VBox {
  /**
   * @param {!SDK.NetworkRequest} request
   */
  constructor(request) {
    super();

    this._tabbedPane = new UI.TabbedPane();
    this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabSelected, this._tabSelected, this);
    this._resourceViewTabSetting = Common.settings.createSetting('cacheStorageViewTab', 'preview');

    this._tabbedPane.appendTab('headers', Common.UIString('Headers'), new Network.RequestHeadersView(request));
    this._tabbedPane.appendTab('preview', Common.UIString('Preview'), new Network.RequestPreviewView(request));
    this._tabbedPane.show(this.element);
  }

  /**
   * @override
   */
  wasShown() {
    super.wasShown();
    this._selectTab();
  }

  /**
   * @param {string=} tabId
   */
  _selectTab(tabId) {
    if (!tabId)
      tabId = this._resourceViewTabSetting.get();
    if (!this._tabbedPane.selectTab(tabId))
      this._tabbedPane.selectTab('headers');
  }

  _tabSelected(event) {
    if (!event.data.isUserGesture)
      return;
    this._resourceViewTabSetting.set(event.data.tabId);
  }
};
