/*
 * Copyright (C) 2008 Nokia Inc.  All rights reserved.
 * Copyright (C) 2013 Samsung Electronics. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED ``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 APPLE INC. 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.
 */

Resources.DOMStorageItemsView = class extends Resources.StorageItemsView {
  /**
   * @param {!Resources.DOMStorage} domStorage
   */
  constructor(domStorage) {
    super(Common.UIString('DOM Storage'), 'domStoragePanel');

    this._domStorage = domStorage;

    this.element.classList.add('storage-view', 'table');

    const columns = /** @type {!Array<!DataGrid.DataGrid.ColumnDescriptor>} */ ([
      {id: 'key', title: Common.UIString('Key'), sortable: false, editable: true, longText: true, weight: 50},
      {id: 'value', title: Common.UIString('Value'), sortable: false, editable: true, longText: true, weight: 50}
    ]);
    this._dataGrid = new DataGrid.DataGrid(columns, this._editingCallback.bind(this), this._deleteCallback.bind(this));
    this._dataGrid.addEventListener(
        DataGrid.DataGrid.Events.SelectedNode,
        event => this._previewEntry(/** @type {!DataGrid.DataGridNode} */ (event.data)));
    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.DeselectedNode, event => this._previewEntry(null));
    this._dataGrid.setStriped(true);
    this._dataGrid.setName('DOMStorageItemsView');

    this._splitWidget = new UI.SplitWidget(false, false);
    this._splitWidget.show(this.element);
    this._splitWidget.setSecondIsSidebar(true);

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

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

    this._showPreview(null, null);

    this._eventListeners = [];
    this.setStorage(domStorage);
  }

  /**
   * @param {!Resources.DOMStorage} domStorage
   */
  setStorage(domStorage) {
    Common.EventTarget.removeEventListeners(this._eventListeners);
    this._domStorage = domStorage;
    this._eventListeners = [
      this._domStorage.addEventListener(
          Resources.DOMStorage.Events.DOMStorageItemsCleared, this._domStorageItemsCleared, this),
      this._domStorage.addEventListener(
          Resources.DOMStorage.Events.DOMStorageItemRemoved, this._domStorageItemRemoved, this),
      this._domStorage.addEventListener(
          Resources.DOMStorage.Events.DOMStorageItemAdded, this._domStorageItemAdded, this),
      this._domStorage.addEventListener(
          Resources.DOMStorage.Events.DOMStorageItemUpdated, this._domStorageItemUpdated, this),
    ];
    this.refreshItems();
  }

  _domStorageItemsCleared() {
    if (!this.isShowing() || !this._dataGrid)
      return;

    this._dataGrid.rootNode().removeChildren();
    this._dataGrid.addCreationNode(false);
    this.setCanDeleteSelected(false);
  }

  /**
   * @param {!Common.Event} event
   */
  _domStorageItemRemoved(event) {
    if (!this.isShowing() || !this._dataGrid)
      return;

    const storageData = event.data;
    const rootNode = this._dataGrid.rootNode();
    const children = rootNode.children;

    for (let i = 0; i < children.length; ++i) {
      const childNode = children[i];
      if (childNode.data.key === storageData.key) {
        rootNode.removeChild(childNode);
        this.setCanDeleteSelected(children.length > 1);
        return;
      }
    }
  }

  /**
   * @param {!Common.Event} event
   */
  _domStorageItemAdded(event) {
    if (!this.isShowing() || !this._dataGrid)
      return;

    const storageData = event.data;
    const rootNode = this._dataGrid.rootNode();
    const children = rootNode.children;

    for (let i = 0; i < children.length; ++i) {
      if (children[i].data.key === storageData.key)
        return;
    }

    const childNode = new DataGrid.DataGridNode({key: storageData.key, value: storageData.value}, false);
    rootNode.insertChild(childNode, children.length - 1);
  }

  /**
   * @param {!Common.Event} event
   */
  _domStorageItemUpdated(event) {
    if (!this.isShowing() || !this._dataGrid)
      return;

    const storageData = event.data;
    const childNode = this._dataGrid.rootNode().children.find(child => child.data.key === storageData.key);
    if (!childNode || childNode.data.value === storageData.value)
      return;

    childNode.data.value = storageData.value;
    childNode.refresh();
    if (!childNode.selected)
      return;
    this._previewEntry(childNode);
    this.setCanDeleteSelected(true);
  }

  /**
   * @param {!Array<!Array<string>>} items
   */
  _showDOMStorageItems(items) {
    const rootNode = this._dataGrid.rootNode();
    let selectedKey = null;
    for (const node of rootNode.children) {
      if (!node.selected)
        continue;
      selectedKey = node.data.key;
      break;
    }
    rootNode.removeChildren();
    let selectedNode = null;
    const filteredItems = item => `${item[0]} ${item[1]}`;
    for (const item of this.filter(items, filteredItems)) {
      const key = item[0];
      const value = item[1];
      const node = new DataGrid.DataGridNode({key: key, value: value}, false);
      node.selectable = true;
      rootNode.appendChild(node);
      if (!selectedNode || key === selectedKey)
        selectedNode = node;
    }
    if (selectedNode)
      selectedNode.selected = true;
    this._dataGrid.addCreationNode(false);
    this.setCanDeleteSelected(!!selectedNode);
  }

  /**
   * @override
   */
  deleteSelectedItem() {
    if (!this._dataGrid || !this._dataGrid.selectedNode)
      return;

    this._deleteCallback(this._dataGrid.selectedNode);
  }

  /**
   * @override
   */
  refreshItems() {
    this._domStorage.getItems().then(items => items && this._showDOMStorageItems(items));
  }

  /**
   * @override
   */
  deleteAllItems() {
    this._domStorage.clear();
    // explicitly clear the view because the event won't be fired when it has no items
    this._domStorageItemsCleared();
  }

  _editingCallback(editingNode, columnIdentifier, oldText, newText) {
    const domStorage = this._domStorage;
    if (columnIdentifier === 'key') {
      if (typeof oldText === 'string')
        domStorage.removeItem(oldText);
      domStorage.setItem(newText, editingNode.data.value || '');
      this._removeDupes(editingNode);
    } else {
      domStorage.setItem(editingNode.data.key || '', newText);
    }
  }

  /**
   * @param {!DataGrid.DataGridNode} masterNode
   */
  _removeDupes(masterNode) {
    const rootNode = this._dataGrid.rootNode();
    const children = rootNode.children;
    for (let i = children.length - 1; i >= 0; --i) {
      const childNode = children[i];
      if ((childNode.data.key === masterNode.data.key) && (masterNode !== childNode))
        rootNode.removeChild(childNode);
    }
  }

  _deleteCallback(node) {
    if (!node || node.isCreationNode)
      return;

    if (this._domStorage)
      this._domStorage.removeItem(node.data.key);
  }

  /**
   * @param {?UI.Widget} preview
   * @param {?string} value
   */
  _showPreview(preview, value) {
    if (this._preview && this._previewValue === value)
      return;
    if (this._preview)
      this._preview.detach();
    if (!preview)
      preview = new UI.EmptyWidget(Common.UIString('Select a value to preview'));
    this._previewValue = value;
    this._preview = preview;
    preview.show(this._previewPanel.contentElement);
  }

  /**
   * @param {?DataGrid.DataGridNode} entry
   */
  async _previewEntry(entry) {
    const value = entry && entry.data && entry.data.value;
    if (!value) {
      this._showPreview(null, value);
      return;
    }
    const protocol = this._domStorage.isLocalStorage ? 'localstorage' : 'sessionstorage';
    const url = `${protocol}://${entry.key}`;
    const provider =
        Common.StaticContentProvider.fromString(url, Common.resourceTypes.XHR, /** @type {string} */ (value));
    const preview = await SourceFrame.PreviewFactory.createPreview(provider, 'text/plain');
    // Selection could've changed while the preview was loaded
    if (!entry.selected)
      return;
    this._showPreview(preview, value);
  }
};
