// 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:
  var DRAFT_MAX_AGE = 24*60*60*1000;

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

  Polymer({
    is: 'gr-storage',

    properties: {
      _lastCleanup: Number,
      _storage: {
        type: Object,
        value: function() {
          return window.localStorage;
        },
      },
    },

    getDraftComment: function(location) {
      this._cleanupDrafts();
      return this._getObject(this._getDraftKey(location));
    },

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

    eraseDraftComment: function(location) {
      var key = this._getDraftKey(location);
      this._storage.removeItem(key);
    },

    _getDraftKey: function(location) {
      return ['draft', location.changeNum, location.patchNum, location.path,
          location.line].join(':');
    },

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

      var draft;
      for (var key in this._storage) {
        if (key.indexOf('draft:') === 0) {
          draft = this._getObject(key);
          if (Date.now() - draft.updated > DRAFT_MAX_AGE) {
            this._storage.removeItem(key);
          }
        }
      }
    },

    _getObject: function(key) {
      var serial = this._storage.getItem(key);
      if (!serial) { return null; }
      return JSON.parse(serial);
    },

    _setObject: function(key, obj) {
      this._storage.setItem(key, JSON.stringify(obj));
    },
  });
})();
