// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

var mercury = require('mercury');
var _ = require('lodash');
var EventEmitter = require('events').EventEmitter;

var arraySet = require('../../lib/array-set');
var store = require('../../lib/store');
var freeze = require('../../lib/mercury/freeze');
var sortedPush = require('../../lib/mercury/sorted-push-array');

var namespaceService = require('../namespace/service');
var namespaceItem = require('../namespace/item');

var log = require('../../lib/log')('services:bookmarks:service');

module.exports = {
  getAll: getAll,
  bookmark: bookmark,
  isBookmarked: isBookmarked
};

// Data is loaded from and saved to this key in the store.
var USER_BOOKMARKS_KEY = 'bookmarks-store-key';

// Singleton state for all the bookmarks.
var bookmarksObs = mercury.array([]);

/*
 * Gets all the namespace items that are bookmarked
 * As new bookmarks become available/removed the observable array will change
 * to reflect the changes.
 *
 * The observable result has an events property which is an EventEmitter
 * and emits 'end', 'itemError' events.
 *
 * @return {Promise.<mercury.array>} Promise of an observable array
 * of bookmark items
 */
function getAll() {
  // Empty out the array
  bookmarksObs.splice(0, bookmarksObs.getLength());
  var immutableBookmarksObs = freeze(bookmarksObs);
  immutableBookmarksObs.events = new EventEmitter();

  return loadKeys().then(getBookmarkItems);

  function getBookmarkItems(names) {
    var allItems = names.map(function(name) {
      return addNamespaceItem(name).catch(function(err) {
        immutableBookmarksObs.events.emit('itemError', {
          name: name,
          error: err
        });
        log.warn('Failed to create item for "' + name + '"', err);
      });
    });

    Promise.all(allItems).then(function() {
      immutableBookmarksObs.events.emit('end');
    }).catch(function() {
      immutableBookmarksObs.events.emit('end');
    });

    return immutableBookmarksObs;
  }
}

/*
 * Gets the namespace items for a name and adds it to the observable array
 */
function addNamespaceItem(name) {
  return namespaceService.getNamespaceItem(name)
    .then(function(item) {
      var sorter = 'objectName';
      sortedPush(bookmarksObs, item, sorter);
    }).catch(function(err) {
      // Add the object, anyway. It will show as inaccessible.
      sortedPush(bookmarksObs, namespaceItem.createItem({
        objectName: name
      }), 'objectName');
      throw err;
    });
}

/*
 * Whether a specific name is bookmarked or not
 * @return {Promise.<boolean>} Promise indicating a name is bookmarked
 */
function isBookmarked(name) {
  return loadKeys().then(function(keys) {
    return (keys && keys.indexOf(name) >= 0);
  });
}

/*
 * Bookmarks/Unbookmarks a name.
 * @return {Promise.<void>} Promise indicating whether operation succeeded.
 */
function bookmark(name, isBookmarked) {
  if (isBookmarked) {
    // new bookmark, add it to the state
    addNamespaceItem(name).catch(function(err) {
      log.warn('Bookmarking inaccessible item "' + name + '"', err);
    });
  } else {
    // remove bookmark
    arraySet.set(bookmarksObs, null, false, indexOf.bind(null, name));
  }

  // update store
  return loadKeys().then(function(keys) {
    keys = keys || []; // Initialize the bookmarks, if none were loaded.
    arraySet.set(keys, name, isBookmarked);
    return store.setValue(USER_BOOKMARKS_KEY, keys);
  });
}

/*
 * Check the observe array for the index of the given item. -1 if not present.
 */
function indexOf(name) {
  return _.findIndex(bookmarksObs(), function(bookmark) {
    // Since bookmarks can be assigned out of order, check for undefined.
    return bookmark !== undefined && name === bookmark.objectName;
  });
}

/*
 * Loads all the bookmarked names from the store
 */
function loadKeys() {
  return store.getValue(USER_BOOKMARKS_KEY).then(function(keys) {
    keys = keys || [];
    return keys.filter(function(key, index, self) {
      // only return unique and existing values
      return key !== null &&
        key !== undefined &&
        self.indexOf(key) === index;
    });
  });
}