/**
 * @license
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
(function() {
  'use strict';

  const DURATION_DAY = 24 * 60 * 60 * 1000;

  // Clean up old entries no more frequently than one day.
  const CLEANUP_THROTTLE_INTERVAL = DURATION_DAY;

  const CLEANUP_PREFIXES_MAX_AGE_MAP = {
    // respectfultip has a 3 day expiration
    'respectfultip:': 3 * DURATION_DAY,
    'draft:': DURATION_DAY,
    'editablecontent:': DURATION_DAY,
  };

  /** @extends Polymer.Element */
  class GrStorage extends Polymer.GestureEventListeners(
      Polymer.LegacyElementMixin(
          Polymer.Element)) {
    static get is() { return 'gr-storage'; }

    static get properties() {
      return {
        _lastCleanup: Number,
        /** @type {?Storage} */
        _storage: {
          type: Object,
          value() {
            return window.localStorage;
          },
        },
        _exceededQuota: {
          type: Boolean,
          value: false,
        },
      };
    }

    getDraftComment(location) {
      this._cleanupItems();
      return this._getObject(this._getDraftKey(location));
    }

    setDraftComment(location, message) {
      const key = this._getDraftKey(location);
      this._setObject(key, {message, updated: Date.now()});
    }

    eraseDraftComment(location) {
      const key = this._getDraftKey(location);
      this._storage.removeItem(key);
    }

    getEditableContentItem(key) {
      this._cleanupItems();
      return this._getObject(this._getEditableContentKey(key));
    }

    setEditableContentItem(key, message) {
      this._setObject(this._getEditableContentKey(key),
          {message, updated: Date.now()});
    }

    getRespectfulTipVisibility() {
      this._cleanupItems();
      return this._getObject('respectfultip:visibility');
    }

    setRespectfulTipVisibility(delayDays = 0) {
      this._cleanupItems();
      this._setObject(
          'respectfultip:visibility',
          {updated: Date.now() + delayDays * DURATION_DAY}
      );
    }

    eraseEditableContentItem(key) {
      this._storage.removeItem(this._getEditableContentKey(key));
    }

    _getDraftKey(location) {
      const range = location.range ?
        `${location.range.start_line}-${location.range.start_character}` +
              `-${location.range.end_character}-${location.range.end_line}` :
        null;
      let key = ['draft', location.changeNum, location.patchNum, location.path,
        location.line || ''].join(':');
      if (range) {
        key = key + ':' + range;
      }
      return key;
    }

    _getEditableContentKey(key) {
      return `editablecontent:${key}`;
    }

    _cleanupItems() {
      // Throttle cleanup to the throttle interval.
      if (this._lastCleanup &&
          Date.now() - this._lastCleanup < CLEANUP_THROTTLE_INTERVAL) {
        return;
      }
      this._lastCleanup = Date.now();

      let item;
      Object.keys(this._storage).forEach(key => {
        Object.keys(CLEANUP_PREFIXES_MAX_AGE_MAP).forEach(prefix => {
          if (key.startsWith(prefix)) {
            item = this._getObject(key);
            const expiration = CLEANUP_PREFIXES_MAX_AGE_MAP[prefix];
            if (Date.now() - item.updated > expiration) {
              this._storage.removeItem(key);
            }
          }
        });
      });
    }

    _getObject(key) {
      const serial = this._storage.getItem(key);
      if (!serial) { return null; }
      return JSON.parse(serial);
    }

    _setObject(key, obj) {
      if (this._exceededQuota) { return; }
      try {
        this._storage.setItem(key, JSON.stringify(obj));
      } catch (exc) {
        // Catch for QuotaExceededError and disable writes on local storage the
        // first time that it occurs.
        if (exc.code === 22) {
          this._exceededQuota = true;
          console.warn('Local storage quota exceeded: disabling');
          return;
        } else {
          throw exc;
        }
      }
    }
  }

  customElements.define(GrStorage.is, GrStorage);
})();
