// 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.
/**
 * @implements {Protocol.StorageDispatcher}
 * @unrestricted
 */
export default class ServiceWorkerCacheModel extends SDK.SDKModel {
  /**
   * Invariant: This model can only be constructed on a ServiceWorker target.
   * @param {!SDK.Target} target
   */
  constructor(target) {
    super(target);
    target.registerStorageDispatcher(this);

    /** @type {!Map<string, !Cache>} */
    this._caches = new Map();

    this._cacheAgent = target.cacheStorageAgent();
    this._storageAgent = target.storageAgent();

    this._securityOriginManager = target.model(SDK.SecurityOriginManager);

    this._originsUpdated = new Set();
    this._throttler = new Common.Throttler(2000);

    /** @type {boolean} */
    this._enabled = false;
  }

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

    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._enabled = true;
  }

  /**
   * @param {string} origin
   */
  clearForOrigin(origin) {
    this._removeOrigin(origin);
    this._addOrigin(origin);
  }

  refreshCacheNames() {
    for (const cache of this._caches.values()) {
      this._cacheRemoved(cache);
    }
    this._caches.clear();
    const securityOrigins = this._securityOriginManager.securityOrigins();
    for (const securityOrigin of securityOrigins) {
      this._loadCacheNames(securityOrigin);
    }
  }

  /**
   * @param {!Cache} cache
   */
  async deleteCache(cache) {
    const response = await this._cacheAgent.invoke_deleteCache({cacheId: cache.cacheId});
    if (response[Protocol.Error]) {
      console.error(`ServiceWorkerCacheAgent error deleting cache ${cache.toString()}: ${response[Protocol.Error]}`);
      return;
    }
    this._caches.delete(cache.cacheId);
    this._cacheRemoved(cache);
  }

  /**
   * @param {!Cache} cache
   * @param {string} request
   * @return {!Promise}
   */
  async deleteCacheEntry(cache, request) {
    const response = await this._cacheAgent.invoke_deleteEntry({cacheId: cache.cacheId, request});
    if (!response[Protocol.Error]) {
      return;
    }
    Common.console.error(Common.UIString(
        'ServiceWorkerCacheAgent error deleting cache entry %s in cache: %s', cache.toString(),
        response[Protocol.Error]));
  }

  /**
   * @param {!Cache} cache
   * @param {number} skipCount
   * @param {number} pageSize
   * @param {string} pathFilter
   * @param {function(!Array.<!Protocol.CacheStorage.DataEntry>, number)} callback
   */
  loadCacheData(cache, skipCount, pageSize, pathFilter, callback) {
    this._requestEntries(cache, skipCount, pageSize, pathFilter, callback);
  }

  /**
   * @param {!Cache} cache
   * @param {string} pathFilter
   * @param {function(!Array.<!Protocol.CacheStorage.DataEntry>, number)} callback
   */
  loadAllCacheData(cache, pathFilter, callback) {
    this._requestAllEntries(cache, pathFilter, callback);
  }

  /**
   * @return {!Array.<!Cache>}
   */
  caches() {
    const caches = new Array();
    for (const cache of this._caches.values()) {
      caches.push(cache);
    }
    return caches;
  }

  /**
   * @override
   */
  dispose() {
    for (const cache of this._caches.values()) {
      this._cacheRemoved(cache);
    }
    this._caches.clear();
    if (this._enabled) {
      this._securityOriginManager.removeEventListener(
          SDK.SecurityOriginManager.Events.SecurityOriginAdded, this._securityOriginAdded, this);
      this._securityOriginManager.removeEventListener(
          SDK.SecurityOriginManager.Events.SecurityOriginRemoved, this._securityOriginRemoved, this);
    }
  }

  _addOrigin(securityOrigin) {
    this._loadCacheNames(securityOrigin);
    if (this._isValidSecurityOrigin(securityOrigin)) {
      this._storageAgent.trackCacheStorageForOrigin(securityOrigin);
    }
  }

  /**
   * @param {string} securityOrigin
   */
  _removeOrigin(securityOrigin) {
    for (const opaqueId of this._caches.keys()) {
      const cache = this._caches.get(opaqueId);
      if (cache.securityOrigin === securityOrigin) {
        this._caches.delete(opaqueId);
        this._cacheRemoved(cache);
      }
    }
    if (this._isValidSecurityOrigin(securityOrigin)) {
      this._storageAgent.untrackCacheStorageForOrigin(securityOrigin);
    }
  }

  /**
   * @param {string} securityOrigin
   * @return {boolean}
   */
  _isValidSecurityOrigin(securityOrigin) {
    const parsedURL = Common.ParsedURL.fromString(securityOrigin);
    return !!parsedURL && parsedURL.scheme.startsWith('http');
  }

  /**
   * @param {string} securityOrigin
   */
  async _loadCacheNames(securityOrigin) {
    const caches = await this._cacheAgent.requestCacheNames(securityOrigin);
    if (!caches) {
      return;
    }
    this._updateCacheNames(securityOrigin, caches);
  }

  /**
   * @param {string} securityOrigin
   * @param {!Array} cachesJson
   */
  _updateCacheNames(securityOrigin, cachesJson) {
    /**
     * @param {!Cache} cache
     * @this {ServiceWorkerCacheModel}
     */
    function deleteAndSaveOldCaches(cache) {
      if (cache.securityOrigin === securityOrigin && !updatingCachesIds.has(cache.cacheId)) {
        oldCaches.set(cache.cacheId, cache);
        this._caches.delete(cache.cacheId);
      }
    }

    /** @type {!Set<string>} */
    const updatingCachesIds = new Set();
    /** @type {!Map<string, !Cache>} */
    const newCaches = new Map();
    /** @type {!Map<string, !Cache>} */
    const oldCaches = new Map();

    for (const cacheJson of cachesJson) {
      const cache = new Cache(this, cacheJson.securityOrigin, cacheJson.cacheName, cacheJson.cacheId);
      updatingCachesIds.add(cache.cacheId);
      if (this._caches.has(cache.cacheId)) {
        continue;
      }
      newCaches.set(cache.cacheId, cache);
      this._caches.set(cache.cacheId, cache);
    }
    this._caches.forEach(deleteAndSaveOldCaches, this);
    newCaches.forEach(this._cacheAdded, this);
    oldCaches.forEach(this._cacheRemoved, this);
  }

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

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

  /**
   * @param {!Cache} cache
   */
  _cacheAdded(cache) {
    this.dispatchEventToListeners(Events.CacheAdded, {model: this, cache: cache});
  }

  /**
   * @param {!Cache} cache
   */
  _cacheRemoved(cache) {
    this.dispatchEventToListeners(Events.CacheRemoved, {model: this, cache: cache});
  }

  /**
   * @param {!Cache} cache
   * @param {number} skipCount
   * @param {number} pageSize
   * @param {string} pathFilter
   * @param {function(!Array<!Protocol.CacheStorage.DataEntry>, number)} callback
   */
  async _requestEntries(cache, skipCount, pageSize, pathFilter, callback) {
    const response =
        await this._cacheAgent.invoke_requestEntries({cacheId: cache.cacheId, skipCount, pageSize, pathFilter});
    if (response[Protocol.Error]) {
      console.error('ServiceWorkerCacheAgent error while requesting entries: ', response[Protocol.Error]);
      return;
    }
    callback(response.cacheDataEntries, response.returnCount);
  }

  /**
   * @param {!Cache} cache
   * @param {string} pathFilter
   * @param {function(!Array<!Protocol.CacheStorage.DataEntry>, number)} callback
   */
  async _requestAllEntries(cache, pathFilter, callback) {
    const response = await this._cacheAgent.invoke_requestEntries({cacheId: cache.cacheId, pathFilter});
    if (response[Protocol.Error]) {
      console.error('ServiceWorkerCacheAgent error while requesting entries: ', response[Protocol.Error]);
      return;
    }
    callback(response.cacheDataEntries, response.returnCount);
  }

  /**
   * @param {string} origin
   * @override
   */
  cacheStorageListUpdated(origin) {
    this._originsUpdated.add(origin);

    this._throttler.schedule(() => {
      const promises = Array.from(this._originsUpdated, origin => this._loadCacheNames(origin));
      this._originsUpdated.clear();
      return Promise.all(promises);
    });
  }

  /**
   * @param {string} origin
   * @param {string} cacheName
   * @override
   */
  cacheStorageContentUpdated(origin, cacheName) {
    this.dispatchEventToListeners(Events.CacheStorageContentUpdated, {origin: origin, cacheName: cacheName});
  }

  /**
   * @param {string} origin
   * @override
   */
  indexedDBListUpdated(origin) {
  }

  /**
   * @param {string} origin
   * @param {string} databaseName
   * @param {string} objectStoreName
   * @override
   */
  indexedDBContentUpdated(origin, databaseName, objectStoreName) {
  }
}

/** @enum {symbol} */
export const Events = {
  CacheAdded: Symbol('CacheAdded'),
  CacheRemoved: Symbol('CacheRemoved'),
  CacheStorageContentUpdated: Symbol('CacheStorageContentUpdated')
};

/**
 * @unrestricted
 */
export class Cache {
  /**
   * @param {!ServiceWorkerCacheModel} model
   * @param {string} securityOrigin
   * @param {string} cacheName
   * @param {string} cacheId
   */
  constructor(model, securityOrigin, cacheName, cacheId) {
    this._model = model;
    this.securityOrigin = securityOrigin;
    this.cacheName = cacheName;
    this.cacheId = cacheId;
  }

  /**
   * @param {!Cache} cache
   * @return {boolean}
   */
  equals(cache) {
    return this.cacheId === cache.cacheId;
  }

  /**
   * @override
   * @return {string}
   */
  toString() {
    return this.securityOrigin + this.cacheName;
  }

  /**
   * @param {string} url
   * @param {!Array.<!SDK.NetworkRequest.NameValue>} requestHeaders
   * @return {!Promise<?Protocol.CacheStorage.CachedResponse>}
   */
  requestCachedResponse(url, requestHeaders) {
    return this._model._cacheAgent.requestCachedResponse(this.cacheId, url, requestHeaders);
  }
}

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

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

/** @constructor */
SDK.ServiceWorkerCacheModel = ServiceWorkerCacheModel;

/** @enum {symbol} */
SDK.ServiceWorkerCacheModel.Events = Events;

/** @constructor */
SDK.ServiceWorkerCacheModel.Cache = Cache;

SDK.SDKModel.register(SDK.ServiceWorkerCacheModel, SDK.Target.Capability.Storage, false);
