// Copyright (c) 2016 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 {SDK.TargetManager.Observer}
 */
Resources.ClearStorageView = class extends UI.ThrottledWidget {
  constructor() {
    super(true, 1000);
    const types = Protocol.Storage.StorageType;
    this._pieColors = new Map([
      [types.Appcache, 'rgb(110, 161, 226)'],        // blue
      [types.Cache_storage, 'rgb(229, 113, 113)'],   // red
      [types.Cookies, 'rgb(239, 196, 87)'],          // yellow
      [types.Indexeddb, 'rgb(155, 127, 230)'],       // purple
      [types.Local_storage, 'rgb(116, 178, 102)'],   // green
      [types.Service_workers, 'rgb(255, 167, 36)'],  // orange
      [types.Websql, 'rgb(203, 220, 56)'],           // lime
    ]);

    this._reportView = new UI.ReportView(Common.UIString('Clear storage'));
    this._reportView.registerRequiredCSS('resources/clearStorageView.css');
    this._reportView.element.classList.add('clear-storage-header');
    this._reportView.show(this.contentElement);
    /** @type {?SDK.Target} */
    this._target = null;
    /** @type {?string} */
    this._securityOrigin = null;

    this._settings = new Map();
    for (const type of Resources.ClearStorageView.AllStorageTypes) {
      this._settings.set(type, Common.settings.createSetting('clear-storage-' + type, true));
    }

    const quota = this._reportView.appendSection(Common.UIString('Usage'));
    this._quotaRow = quota.appendSelectableRow();
    const learnMoreRow = quota.appendRow();
    const learnMore = UI.XLink.create(
        'https://developers.google.com/web/tools/chrome-devtools/progressive-web-apps#opaque-responses',
        ls`Learn more`);
    learnMoreRow.appendChild(learnMore);
    this._quotaUsage = null;
    this._pieChart = new PerfUI.PieChart(
        {chartName: ls`Storage Usage`, size: 110, formatter: Number.bytesToString, showLegend: true});
    const usageBreakdownRow = quota.appendRow();
    usageBreakdownRow.classList.add('usage-breakdown-row');
    usageBreakdownRow.appendChild(this._pieChart.element);

    const clearButtonSection = this._reportView.appendSection('', 'clear-storage-button').appendRow();
    this._clearButton = UI.createTextButton(ls`Clear site data`, this._clear.bind(this));
    clearButtonSection.appendChild(this._clearButton);

    const application = this._reportView.appendSection(Common.UIString('Application'));
    this._appendItem(application, Common.UIString('Unregister service workers'), 'service_workers');
    application.markFieldListAsGroup();

    const storage = this._reportView.appendSection(Common.UIString('Storage'));
    this._appendItem(storage, Common.UIString('Local and session storage'), 'local_storage');
    this._appendItem(storage, Common.UIString('IndexedDB'), 'indexeddb');
    this._appendItem(storage, Common.UIString('Web SQL'), 'websql');
    this._appendItem(storage, Common.UIString('Cookies'), 'cookies');
    storage.markFieldListAsGroup();

    const caches = this._reportView.appendSection(Common.UIString('Cache'));
    this._appendItem(caches, Common.UIString('Cache storage'), 'cache_storage');
    this._appendItem(caches, Common.UIString('Application cache'), 'appcache');
    caches.markFieldListAsGroup();

    SDK.targetManager.observeTargets(this);
  }

  /**
   * @param {!UI.ReportView.Section} section
   * @param {string} title
   * @param {string} settingName
   */
  _appendItem(section, title, settingName) {
    const row = section.appendRow();
    row.appendChild(UI.SettingsUI.createSettingCheckbox(title, this._settings.get(settingName), true));
  }

  /**
   * @override
   * @param {!SDK.Target} target
   */
  targetAdded(target) {
    if (this._target) {
      return;
    }
    this._target = target;
    const securityOriginManager = target.model(SDK.SecurityOriginManager);
    this._updateOrigin(
        securityOriginManager.mainSecurityOrigin(), securityOriginManager.unreachableMainSecurityOrigin());
    securityOriginManager.addEventListener(
        SDK.SecurityOriginManager.Events.MainSecurityOriginChanged, this._originChanged, this);
  }

  /**
   * @override
   * @param {!SDK.Target} target
   */
  targetRemoved(target) {
    if (this._target !== target) {
      return;
    }
    const securityOriginManager = target.model(SDK.SecurityOriginManager);
    securityOriginManager.removeEventListener(
        SDK.SecurityOriginManager.Events.MainSecurityOriginChanged, this._originChanged, this);
  }

  /**
   * @param {!Common.Event} event
   */
  _originChanged(event) {
    const mainOrigin = /** *@type {string} */ (event.data.mainSecurityOrigin);
    const unreachableMainOrigin = /** @type {string} */ (event.data.unreachableMainSecurityOrigin);
    this._updateOrigin(mainOrigin, unreachableMainOrigin);
  }

  /**
   * @param {string} mainOrigin
   * @param {string} unreachableMainOrigin
   */
  _updateOrigin(mainOrigin, unreachableMainOrigin) {
    if (unreachableMainOrigin) {
      this._securityOrigin = unreachableMainOrigin;
      this._reportView.setSubtitle(ls`${unreachableMainOrigin} (failed to load)`);
    } else {
      this._securityOrigin = mainOrigin;
      this._reportView.setSubtitle(mainOrigin);
    }

    this.doUpdate();
  }

  _clear() {
    if (!this._securityOrigin) {
      return;
    }
    const selectedStorageTypes = [];
    for (const type of this._settings.keys()) {
      if (this._settings.get(type).get()) {
        selectedStorageTypes.push(type);
      }
    }

    if (this._target) {
      Resources.ClearStorageView.clear(this._target, this._securityOrigin, selectedStorageTypes);
    }

    this._clearButton.disabled = true;
    const label = this._clearButton.textContent;
    this._clearButton.textContent = Common.UIString('Clearing...');
    setTimeout(() => {
      this._clearButton.disabled = false;
      this._clearButton.textContent = label;
    }, 500);
  }

  /**
   * @param {!SDK.Target} target
   * @param {string} securityOrigin
   * @param {!Array<string>} selectedStorageTypes
   */
  static clear(target, securityOrigin, selectedStorageTypes) {
    target.storageAgent().clearDataForOrigin(securityOrigin, selectedStorageTypes.join(','));

    const set = new Set(selectedStorageTypes);
    const hasAll = set.has(Protocol.Storage.StorageType.All);
    if (set.has(Protocol.Storage.StorageType.Cookies) || hasAll) {
      const cookieModel = target.model(SDK.CookieModel);
      if (cookieModel) {
        cookieModel.clear();
      }
    }

    if (set.has(Protocol.Storage.StorageType.Indexeddb) || hasAll) {
      for (const target of SDK.targetManager.targets()) {
        const indexedDBModel = target.model(Resources.IndexedDBModel);
        if (indexedDBModel) {
          indexedDBModel.clearForOrigin(securityOrigin);
        }
      }
    }

    if (set.has(Protocol.Storage.StorageType.Local_storage) || hasAll) {
      const storageModel = target.model(Resources.DOMStorageModel);
      if (storageModel) {
        storageModel.clearForOrigin(securityOrigin);
      }
    }

    if (set.has(Protocol.Storage.StorageType.Websql) || hasAll) {
      const databaseModel = target.model(Resources.DatabaseModel);
      if (databaseModel) {
        databaseModel.disable();
        databaseModel.enable();
      }
    }

    if (set.has(Protocol.Storage.StorageType.Cache_storage) || hasAll) {
      const target = SDK.targetManager.mainTarget();
      const model = target && target.model(SDK.ServiceWorkerCacheModel);
      if (model) {
        model.clearForOrigin(securityOrigin);
      }
    }

    if (set.has(Protocol.Storage.StorageType.Appcache) || hasAll) {
      const appcacheModel = target.model(Resources.ApplicationCacheModel);
      if (appcacheModel) {
        appcacheModel.reset();
      }
    }
  }

  /**
   * @override
   * @return {!Promise<?>}
   */
  async doUpdate() {
    if (!this._securityOrigin) {
      return;
    }

    const securityOrigin = /** @type {string} */ (this._securityOrigin);
    const response = await this._target.storageAgent().invoke_getUsageAndQuota({origin: securityOrigin});
    if (response[Protocol.Error]) {
      this._quotaRow.textContent = '';
      this._resetPieChart(0);
      return;
    }
    this._quotaRow.textContent = Common.UIString(
        '%s used out of %s storage quota.\xA0', Number.bytesToString(response.usage),
        Number.bytesToString(response.quota));
    if (response.quota < 125829120) {  // 120 MB
      this._quotaRow.title = ls`Storage quota is limited in Incognito mode`;
      this._quotaRow.appendChild(UI.Icon.create('smallicon-info'));
    }

    if (!this._quotaUsage || this._quotaUsage !== response.usage) {
      this._quotaUsage = response.usage;
      this._resetPieChart(response.usage);
      for (const usageForType of response.usageBreakdown.sort((a, b) => b.usage - a.usage)) {
        const value = usageForType.usage;
        if (!value) {
          continue;
        }
        const title = this._getStorageTypeName(usageForType.storageType);
        const color = this._pieColors.get(usageForType.storageType) || '#ccc';
        this._pieChart.addSlice(value, color, title);
      }
    }

    this._usageUpdatedForTest(response.usage, response.quota, response.usageBreakdown);
    this.update();
  }

  /**
   * @param {number} total
   */
  _resetPieChart(total) {
    this._pieChart.setTotal(total);
  }

  /**
   * @param {string} type
   * @return {string}
   */
  _getStorageTypeName(type) {
    switch (type) {
      case Protocol.Storage.StorageType.File_systems:
        return Common.UIString('File System');
      case Protocol.Storage.StorageType.Websql:
        return Common.UIString('Web SQL');
      case Protocol.Storage.StorageType.Appcache:
        return Common.UIString('Application Cache');
      case Protocol.Storage.StorageType.Indexeddb:
        return Common.UIString('IndexedDB');
      case Protocol.Storage.StorageType.Cache_storage:
        return Common.UIString('Cache Storage');
      case Protocol.Storage.StorageType.Service_workers:
        return Common.UIString('Service Workers');
      default:
        return Common.UIString('Other');
    }
  }

  /**
   * @param {number} usage
   * @param {number} quota
   * @param {!Array<!Protocol.Storage.UsageForType>} usageBreakdown
   */
  _usageUpdatedForTest(usage, quota, usageBreakdown) {
  }
};

Resources.ClearStorageView.AllStorageTypes = [
  Protocol.Storage.StorageType.Appcache, Protocol.Storage.StorageType.Cache_storage,
  Protocol.Storage.StorageType.Cookies, Protocol.Storage.StorageType.Indexeddb,
  Protocol.Storage.StorageType.Local_storage, Protocol.Storage.StorageType.Service_workers,
  Protocol.Storage.StorageType.Websql
];

/**
 * @implements {UI.ActionDelegate}
 */
Resources.ClearStorageView.ActionDelegate = class {
  /**
   * @override
   * @param {!UI.Context} context
   * @param {string} actionId
   * @return {boolean}
   */
  handleAction(context, actionId) {
    switch (actionId) {
      case 'resources.clear':
        return this._handleClear();
    }
    return false;
  }

  /**
   * @return {boolean}
   */
  _handleClear() {
    const target = SDK.targetManager.mainTarget();
    if (!target) {
      return false;
    }
    const resourceTreeModel = target.model(SDK.ResourceTreeModel);
    if (!resourceTreeModel) {
      return false;
    }
    const securityOrigin = resourceTreeModel.getMainSecurityOrigin();
    if (!securityOrigin) {
      return false;
    }

    Resources.ClearStorageView.clear(target, securityOrigin, Resources.ClearStorageView.AllStorageTypes);
    return true;
  }
};
