Source: src/js/collections/bookkeeper/Usages.js

"use strict";

define(["jquery", "underscore", "backbone", "models/bookkeeper/Usage", "models/bookkeeper/Quota"],
  function($, _, Backbone, Usage, Quota) {

  /**
   * @class Usages
   * @classdesc A Usages collection is a collection of Usage Models which track
   * objects that use a portion of a Quota. Each Quota is associated with one or more
   * Usage models, so this collection keeps all those associated Usages together in one collection.
   * This collection also stores a reference to the Quota model associated with these Usages.
   * @classcategory Collections/Bookkeeper
   * @since 2.14.0
   * @extends Backbone.Collection
   */
  var Usages = Backbone.Collection.extend(
    /** @lends Usages.prototype */ {

    /**
    * The class/model that is contained in this collection.
    * @type {Backbone.Model}
    */
    model: Usage,

    /**
    * A reference to a Quota model that this collection of Usages is associated with.
    * @type {Quota}
    */
    quota: null,

    /**
    * A list of query parameters that are supported by the Bookkeeper Usages API. These
    * query parameters can be passed to {@link Usages#fetch} in the `options` object, and they
    * will be used during the fetch.
    * @type {string[]}
    */
    queryParams: ["quotaType", "subscriber"],

    /**
    * Constructs a URL string for fetching this collection and returns it
    * @param {Object} [options]
    * @property {string} options.quotaType  The Usage quotaType to fetch
    * @property {string} options.subscriber  The user or group subject associated with these Usages
    * @returns {string} The URL string
    */
    url: function(options){

      var url = "";

      //Use the attributes from the options object for the URL, if it is passed to this function
      if( typeof options == "object" ){

        _.each( this.queryParams, function(name){
          if( typeof options[name] !== "undefined"){
            if( url.length == 0 ){
              url += "?";
            }
            else{
              url += "&";
            }

            url += name + "=" + encodeURIComponent(options[name]);
          }
        });

      }

      //Prepend the Bookkeeper Usages URL to the url query parameters string
      url = MetacatUI.appModel.get("bookkeeperUsagesUrl") + url;

      return url;

    },

    /**
    * Fetches a list of Usages from the DataONE Bookkeeper service, parses them, and
    * stores them on this collection.
    * @param {Object} [options]
    * @property {string} options.quotaType  The Usage quotaType to fetch
    * @property {string} options.subscriber  The user or group subject associated with these Usages
    */
    fetch: function(options){

      var fetchOptions = {
        url: this.url(options)
      }

      fetchOptions = Object.assign(fetchOptions, MetacatUI.appUserModel.createAjaxSettings());

      //Call Backbone.Collection.fetch to retrieve the info
      return Backbone.Collection.prototype.fetch.call(this, fetchOptions);

    },

    /**
    * Parses the fetch() of this collection. Bookkeeper returns JSON already, so there
    * isn't much parsing to do.
    * @returns {JSON} The collection data in JSON form
    */
    parse: function(response){
      return response.usages;
    },

    /**
    * Merges another collection of models with this collection by matching instanceId to seriesId/id.
    * A reference to the model from the otherCollection is stored in the corresponding Usage model.
    * @type {DataPackage|SolrResults}
    */
    mergeCollections: function(otherCollection){

      //Iterate over each Usage in this collection
      this.each(function(usage){

        //Find the other model that matches this Usage
        var match = otherCollection.find(function(otherModel){
          //Make a match on the seriesId
          if( _.contains(otherModel.get("seriesId"), usage.get("instanceId")) ){
            return true;
          }
          //Make a match on the id
          else if( _.contains(otherModel.get("id"), usage.get("instanceId")) ){
            return true;
          }
          else{
            return false;
          }
        });

        //If a match is found, store a reference in each model
        if( match ){
          usage.set(match.type, match);
          match.set("usageModel", this);
        }

      }, this);

    }

  });

  return Usages;
});