// 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;
    this._refreshThrottler = new Common.Throttler(300);
    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);

    const entryPathFilterBox = new UI.ToolbarInput(ls`Filter by Path`, '', 1);
    editorToolbar.appendToolbarItem(entryPathFilterBox);
    const entryPathFilterThrottler = new Common.Throttler(300);
    this._entryPathFilter = '';
    entryPathFilterBox.addEventListener(UI.ToolbarInput.Event.TextChanged, () => {
      entryPathFilterThrottler.schedule(() => {
        this._entryPathFilter = entryPathFilterBox.value();
        return this._updateData(true);
      });
    });

    this._returnCount = /** @type {?number} */ (null);
    this._summaryBarElement = /** @type {?Element} */ (null);
    this._loadingPromise = /** @type {?Promise} */ (null);

    this.update(cache);
  }

  _resetDataGrid() {
    if (this._dataGrid) {
      this._dataGrid.asWidget().detach();
    }
    this._dataGrid = this._createDataGrid();
    const dataGridWidget = this._dataGrid.asWidget();
    this._splitWidget.setSidebarWidget(dataGridWidget);
    dataGridWidget.setMinimumSize(0, 250);
  }

  /**
   * @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 (preview && 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: 'number', title: '#', sortable: false, width: '3px'},
      {id: 'name', title: Common.UIString('Name'), weight: 4, sortable: true},
      {id: 'responseType', title: ls`Response-Type`, weight: 1, align: DataGrid.DataGrid.Align.Right, 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 === 'name') {
      comparator = (a, b) => a._name.localeCompare(b._name);
    } 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;
    } else if (columnId === 'responseType') {
      comparator = (a, b) => a._responseType.localeCompare(b._responseType);
    }

    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 {?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;
    this._resetDataGrid();
    this._updateData(true);
  }

  _updateSummaryBar() {
    if (!this._summaryBarElement) {
      this._summaryBarElement = this.element.createChild('div', 'cache-storage-summary-bar');
    }
    this._summaryBarElement.removeChildren();

    const span = this._summaryBarElement.createChild('span');
    if (this._entryPathFilter) {
      span.textContent = ls`Matching entries: ${this._returnCount}`;
    } else {
      span.textContent = ls`Total entries: ${this._returnCount}`;
    }
  }

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

    /** @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 (let i = 0; i < entries.length; ++i) {
      const entry = entries[i];
      let node = oldEntries.get(entry.requestURL);
      if (!node || node.data.responseTime !== entry.responseTime) {
        node = new Resources.ServiceWorkerCacheView.DataGridNode(i, this._createRequest(entry), entry.responseType);
        node.selectable = true;
      } else {
        node.data.number = i;
      }
      rootNode.appendChild(node);
      if (entry.requestURL === selected) {
        selectedNode = node;
      }
    }
    if (!selectedNode) {
      this._showPreview(null);
    } else {
      selectedNode.revealAndSelect();
    }
    this._updatedForTest();
  }

  /**
   * @param {boolean} force
   */
  async _updateData(force) {
    if (!force && this._loadingPromise) {
      return this._loadingPromise;
    }
    this._refreshButton.setEnabled(false);

    if (this._loadingPromise) {
      return this._loadingPromise;
    }

    this._loadingPromise = new Promise(resolve => {
      this._model.loadAllCacheData(this._cache, this._entryPathFilter, (entries, returnCount) => {
        resolve([entries, returnCount]);
      });
    });

    const [entries, returnCount] = await this._loadingPromise;
    this._updateDataCallback(0, entries, returnCount);
    this._loadingPromise = null;
  }

  /**
   * @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(), request.requestHeaders());
    if (response) {
      contentData.content = isText ? window.atob(response.body) : response.body;
    }
    return contentData;
  }

  _updatedForTest() {
  }
};

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

Resources.ServiceWorkerCacheView.DataGridNode = class extends DataGrid.DataGridNode {
  /**
   * @param {number} number
   * @param {!SDK.NetworkRequest} request
   * @param {!Protocol.CacheStorage.CachedResponseType} responseType
   */
  constructor(number, request, responseType) {
    super(request);
    this._number = number;
    const parsed = new Common.ParsedURL(request.url());
    if (parsed.isValid) {
      this._name = request.url().trimURL(parsed.domain());
    } else {
      this._name = request.url();
    }
    this._request = request;
    this._responseType = responseType;
  }

  /**
   * @override
   * @param {string} columnId
   * @return {!Element}
   */
  createCell(columnId) {
    const cell = this.createTD(columnId);
    let value;
    if (columnId === 'number') {
      value = String(this._number);
    } else if (columnId === 'name') {
      value = this._name;
    } else if (columnId === 'responseType') {
      if (this._responseType === 'opaqueResponse') {
        value = 'opaque';
      } else if (this._responseType === 'opaqueRedirect') {
        value = 'opaqueredirect';
      } else {
        value = this._responseType;
      }
    } 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);
    cell.title = this._request.url();
    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);
  }
};
