/*
 * 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.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * 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 OR ITS 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.
 */

/**
 * @unrestricted
 */
Resources.DOMStorage = class extends Common.Object {
  /**
   * @param {!Resources.DOMStorageModel} model
   * @param {string} securityOrigin
   * @param {boolean} isLocalStorage
   */
  constructor(model, securityOrigin, isLocalStorage) {
    super();
    this._model = model;
    this._securityOrigin = securityOrigin;
    this._isLocalStorage = isLocalStorage;
  }

  /**
   * @param {string} securityOrigin
   * @param {boolean} isLocalStorage
   * @return {!Protocol.DOMStorage.StorageId}
   */
  static storageId(securityOrigin, isLocalStorage) {
    return {securityOrigin: securityOrigin, isLocalStorage: isLocalStorage};
  }

  /** @return {!Protocol.DOMStorage.StorageId} */
  get id() {
    return Resources.DOMStorage.storageId(this._securityOrigin, this._isLocalStorage);
  }

  /** @return {string} */
  get securityOrigin() {
    return this._securityOrigin;
  }

  /** @return {boolean} */
  get isLocalStorage() {
    return this._isLocalStorage;
  }

  /**
   * @return {!Promise<?Array<!Protocol.DOMStorage.Item>>}
   */
  getItems() {
    return this._model._agent.getDOMStorageItems(this.id);
  }

  /**
   * @param {string} key
   * @param {string} value
   */
  setItem(key, value) {
    this._model._agent.setDOMStorageItem(this.id, key, value);
  }

  /**
   * @param {string} key
   */
  removeItem(key) {
    this._model._agent.removeDOMStorageItem(this.id, key);
  }

  clear() {
    this._model._agent.clear(this.id);
  }
};


/** @enum {symbol} */
Resources.DOMStorage.Events = {
  DOMStorageItemsCleared: Symbol('DOMStorageItemsCleared'),
  DOMStorageItemRemoved: Symbol('DOMStorageItemRemoved'),
  DOMStorageItemAdded: Symbol('DOMStorageItemAdded'),
  DOMStorageItemUpdated: Symbol('DOMStorageItemUpdated')
};

/**
 * @unrestricted
 */
Resources.DOMStorageModel = class extends SDK.SDKModel {
  /**
   * @param {!SDK.Target} target
   */
  constructor(target) {
    super(target);

    this._securityOriginManager = target.model(SDK.SecurityOriginManager);
    /** @type {!Object.<string, !Resources.DOMStorage>} */
    this._storages = {};
    this._agent = target.domstorageAgent();
  }

  enable() {
    if (this._enabled) {
      return;
    }

    this.target().registerDOMStorageDispatcher(new Resources.DOMStorageDispatcher(this));
    this._securityOriginManager.addEventListener(
        SDK.SecurityOriginManager.Events.SecurityOriginAdded, this._securityOriginAdded, this);
    this._securityOriginManager.addEventListener(
        SDK.SecurityOriginManager.Events.SecurityOriginRemoved, this._securityOriginRemoved, this);

    for (const securityOrigin of this._securityOriginManager.securityOrigins()) {
      this._addOrigin(securityOrigin);
    }
    this._agent.enable();

    this._enabled = true;
  }

  /**
   * @param {string} origin
   */
  clearForOrigin(origin) {
    if (!this._enabled) {
      return;
    }
    for (const isLocal of [true, false]) {
      const key = this._storageKey(origin, isLocal);
      const storage = this._storages[key];
      storage.clear();
    }
    this._removeOrigin(origin);
    this._addOrigin(origin);
  }

  /**
   * @param {!Common.Event} event
   */
  _securityOriginAdded(event) {
    this._addOrigin(/** @type {string} */ (event.data));
  }

  /**
   * @param {string} securityOrigin
   */
  _addOrigin(securityOrigin) {
    const parsed = new Common.ParsedURL(securityOrigin);
    // These are "opaque" origins which are not supposed to support DOM storage.
    if (!parsed.isValid || parsed.scheme === 'data' || parsed.scheme === 'about' || parsed.scheme === 'javascript') {
      return;
    }

    for (const isLocal of [true, false]) {
      const key = this._storageKey(securityOrigin, isLocal);
      console.assert(!this._storages[key]);
      const storage = new Resources.DOMStorage(this, securityOrigin, isLocal);
      this._storages[key] = storage;
      this.dispatchEventToListeners(Resources.DOMStorageModel.Events.DOMStorageAdded, storage);
    }
  }

  /**
   * @param {!Common.Event} event
   */
  _securityOriginRemoved(event) {
    this._removeOrigin(/** @type {string} */ (event.data));
  }

  /**
   * @param {string} securityOrigin
   */
  _removeOrigin(securityOrigin) {
    for (const isLocal of [true, false]) {
      const key = this._storageKey(securityOrigin, isLocal);
      const storage = this._storages[key];
      if (!storage) {
        continue;
      }
      delete this._storages[key];
      this.dispatchEventToListeners(Resources.DOMStorageModel.Events.DOMStorageRemoved, storage);
    }
  }

  /**
   * @param {string} securityOrigin
   * @param {boolean} isLocalStorage
   * @return {string}
   */
  _storageKey(securityOrigin, isLocalStorage) {
    return JSON.stringify(Resources.DOMStorage.storageId(securityOrigin, isLocalStorage));
  }

  /**
   * @param {!Protocol.DOMStorage.StorageId} storageId
   */
  _domStorageItemsCleared(storageId) {
    const domStorage = this.storageForId(storageId);
    if (!domStorage) {
      return;
    }

    const eventData = {};
    domStorage.dispatchEventToListeners(Resources.DOMStorage.Events.DOMStorageItemsCleared, eventData);
  }

  /**
   * @param {!Protocol.DOMStorage.StorageId} storageId
   * @param {string} key
   */
  _domStorageItemRemoved(storageId, key) {
    const domStorage = this.storageForId(storageId);
    if (!domStorage) {
      return;
    }

    const eventData = {key: key};
    domStorage.dispatchEventToListeners(Resources.DOMStorage.Events.DOMStorageItemRemoved, eventData);
  }

  /**
   * @param {!Protocol.DOMStorage.StorageId} storageId
   * @param {string} key
   * @param {string} value
   */
  _domStorageItemAdded(storageId, key, value) {
    const domStorage = this.storageForId(storageId);
    if (!domStorage) {
      return;
    }

    const eventData = {key: key, value: value};
    domStorage.dispatchEventToListeners(Resources.DOMStorage.Events.DOMStorageItemAdded, eventData);
  }

  /**
   * @param {!Protocol.DOMStorage.StorageId} storageId
   * @param {string} key
   * @param {string} oldValue
   * @param {string} value
   */
  _domStorageItemUpdated(storageId, key, oldValue, value) {
    const domStorage = this.storageForId(storageId);
    if (!domStorage) {
      return;
    }

    const eventData = {key: key, oldValue: oldValue, value: value};
    domStorage.dispatchEventToListeners(Resources.DOMStorage.Events.DOMStorageItemUpdated, eventData);
  }

  /**
   * @param {!Protocol.DOMStorage.StorageId} storageId
   * @return {!Resources.DOMStorage}
   */
  storageForId(storageId) {
    return this._storages[JSON.stringify(storageId)];
  }

  /**
   * @return {!Array.<!Resources.DOMStorage>}
   */
  storages() {
    const result = [];
    for (const id in this._storages) {
      result.push(this._storages[id]);
    }
    return result;
  }
};

SDK.SDKModel.register(Resources.DOMStorageModel, SDK.Target.Capability.DOM, false);

/** @enum {symbol} */
Resources.DOMStorageModel.Events = {
  DOMStorageAdded: Symbol('DOMStorageAdded'),
  DOMStorageRemoved: Symbol('DOMStorageRemoved')
};

/**
 * @implements {Protocol.DOMStorageDispatcher}
 * @unrestricted
 */
Resources.DOMStorageDispatcher = class {
  /**
   * @param {!Resources.DOMStorageModel} model
   */
  constructor(model) {
    this._model = model;
  }

  /**
   * @override
   * @param {!Protocol.DOMStorage.StorageId} storageId
   */
  domStorageItemsCleared(storageId) {
    this._model._domStorageItemsCleared(storageId);
  }

  /**
   * @override
   * @param {!Protocol.DOMStorage.StorageId} storageId
   * @param {string} key
   */
  domStorageItemRemoved(storageId, key) {
    this._model._domStorageItemRemoved(storageId, key);
  }

  /**
   * @override
   * @param {!Protocol.DOMStorage.StorageId} storageId
   * @param {string} key
   * @param {string} value
   */
  domStorageItemAdded(storageId, key, value) {
    this._model._domStorageItemAdded(storageId, key, value);
  }

  /**
   * @override
   * @param {!Protocol.DOMStorage.StorageId} storageId
   * @param {string} key
   * @param {string} oldValue
   * @param {string} value
   */
  domStorageItemUpdated(storageId, key, oldValue, value) {
    this._model._domStorageItemUpdated(storageId, key, oldValue, value);
  }
};
