/**
 * @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';

  // Date cutoff is one day:
  const CLEANUP_MAX_AGE = 24 * 60 * 60 * 1000;

  // Clean up old entries no more frequently than one day.
  const CLEANUP_THROTTLE_INTERVAL = 24 * 60 * 60 * 1000;

  const CLEANUP_PREFIXES = [
    'draft:',
    'editablecontent:',
  ];

  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()});
    }

    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;
      for (const key in this._storage) {
        if (!this._storage.hasOwnProperty(key)) { continue; }
        for (const prefix of CLEANUP_PREFIXES) {
          if (key.startsWith(prefix)) {
            item = this._getObject(key);
            if (Date.now() - item.updated > CLEANUP_MAX_AGE) {
              this._storage.removeItem(key);
            }
            break;
          }
        }
      }
    }

    _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);
})();
