# Source: src/js/views/portals/PortalUsagesView.js

    define(["jquery",
      "underscore",
      "backbone",
      "collections/SolrResults",
      "collections/Filters",
      "collections/bookkeeper/Usages",
      "views/portals/PortalListView",
      "text!templates/portals/portalList.html"],
      function($, _, Backbone, SearchResults, Filters, Usages, PortalListView, Template){

        /**
        * @class PortalUsagesView
        * @classdesc A view that shows a list of Portal Usages
        * @classcategory Views/Portals
        * @extends PortalListView
        * @since 2.14.0
        * @constructor
        */
        return PortalListView.extend(
          /** @lends PortalUsagesView.prototype */{

          /**
          * A reference to the Usages collection that is rendered in this view
          * @type {Usages}
          */
          usagesCollection: null,

          /**
          * Renders this view
          */
          render: function(){

            try{

              //If the "my portals" feature is disabled, exit now
              if(MetacatUI.appModel.get("showMyPortals") === false){
                return;
              }

              //Insert the template
              this.$el.html(this.template());

              if( !this.usagesCollection ){
                this.usagesCollection = new Usages();
              }

              //When in DataONE Plus Preview mode, search for portals in Solr first,
              // then create Usage models for each portal in Solr.
              if( MetacatUI.appModel.get("dataonePlusPreviewMode") ){

                this.listenTo(this.searchResults, "sync", function(){

                  //Create a Usage for each portal found in Solr
                  this.searchResults.each(function(searchResult){
                    this.usagesCollection.add({
                      instanceId: searchResult.get("seriesId"),
                      status: "active",
                      quantity: 1,
                      nodeId: searchResult.get("datasource")
                    });
                  }, this);

                  //Merge the Usages and Search Results
                  this.mergeSearchResults();

                  //Update the view with info about the corresponding Usage model
                  this.showUsageInfo();
                });

                if( MetacatUI.appModel.get("dataonePlusPreviewPortals").length ){

                  this.altReposChecked = 0;
                  this.altReposToCheck = [];
                  this.additionalPortalsToDisplay = [];

                  _.each( MetacatUI.appModel.get("alternateRepositories"), function(altRepo){

                    var portalsInThisRepo = _.where(MetacatUI.appModel.get("dataonePlusPreviewPortals"),
                                              { datasource: altRepo.identifier });

                    if( portalsInThisRepo.length ){

                      var searchResults = new SearchResults();
                      this.listenToOnce(searchResults, "reset", function(){

                        if( searchResults.length ){
                          this.additionalPortalsToDisplay = this.additionalPortalsToDisplay.concat( searchResults.models );
                        }

                        if(typeof this.altReposChecked == "number" ){
                          this.altReposChecked++;
                          if( this.altReposChecked == this.altReposToCheck ){
                            //Call the PortalListView render function
                            PortalListView.prototype.render.call(this);
                          }
                        }

                        //Create a Usage for each portal found in Solr
                        searchResults.each(function(searchResult){
                          this.usagesCollection.add({
                            instanceId: searchResult.get("seriesId"),
                            status: "active",
                            quantity: 1,
                            nodeId: searchResult.get("datasource")
                          });
                        }, this);

                        //Merge the Usages and Search Results
                        this.mergeSearchResults(searchResults);

                        //Update the view with info about the corresponding Usage model
                        this.showUsageInfo();

                      });

                      //Create a Filters() collection
                      var portalFilters = new Filters();
                      portalFilters.mustMatchIds = true;
                      portalFilters.addWritePermissionFilter();
                      portalFilters.add({
                        fields: ["obsoletedBy"],
                        values: ["*"],
                        matchSubstring: false,
                        exclude: true
                      });
                      portalFilters.add({
                        fields: ["datasource"],
                        values: [altRepo.identifier],
                        matchSubstring: false,
                        exclude: false
                      });
                      var portalIds = _.pluck(portalsInThisRepo, "seriesId");
                      portalFilters.add({
                        fields: ["seriesId"],
                        values: portalIds,
                        operator: "OR",
                        matchSubstring: false
                      });

                      searchResults.rows = portalIds.length;
                      searchResults.fields = this.searchFields;

                      searchResults.queryServiceUrl = altRepo.queryServiceUrl;

                      searchResults.setQuery( portalFilters.getQuery() );

                      this.altReposToCheck++;

                      //Get the first page of results
                      searchResults.toPage(0);
                    }

                  }, this);

                  return;

                }

                //Call the PortalListView render function
                PortalListView.prototype.render.call(this);

                //Don't do anything else in this render function
                return;
              }

              //When the collection has been fetched, redner the Usage list
              this.listenToOnce(this.usagesCollection, "sync", this.getSearchResultsForUsages);

              //Listen to the collection for errors
              this.listenToOnce(this.usagesCollection, "error", this.showError);

              //When the SearchResults are retrieved, merge them with the Usages collection
              this.listenToOnce(this.searchResults, "sync", function(){
                this.mergeSearchResults();

                //Update the view with info about the corresponding Usage model
                this.showUsageInfo();
              });

              //Fetch the collection
              this.usagesCollection.fetch({
                quotaType: "portal",
                subject: MetacatUI.appUserModel.get("username")
              });

            }
            catch(e){
              console.error("Failed to render the PortalUsagesView: ", e);
            }

          },

          /**
          * Using the Usages collection, this function creates Filters that search for
          * the portal objects for those Usages
          * @param {Usages} usages The Usages collection to get search results for
          */
          getSearchResultsForUsages: function(usages){

            try{

              //Set the number of portals to the number of usages found
              this.numPortals = this.usagesCollection.length;

              var portalIds = this.usagesCollection.pluck("instanceId");

              //If there are no given filters, create a Filter for the seriesId of each portal Usage
              if( !this.filters && portalIds.length ){
                this.filters = new Filters();

                this.filters.mustMatchIds = true;
                this.filters.add({
                  fields: ["seriesId"],
                  values: portalIds,
                  operator: "OR",
                  matchSubstring: false,
                  exclude: false
                });

                //Only get Portals that the user is an owner of
                this.filters.addWritePermissionFilter();
              }
              //If the filters set on this view is an array of JSON, add it to a Filters collection
              else if( this.filters.length && !Filters.prototype.isPrototypeOf(this.filters) ){
                //Create search filters for finding the portals
                var filters = new Filters();

                filters.add( this.filters );

                this.filters = filters;
              }
              else{
                this.filters = new Filters();
              }

              this.getSearchResults();

            }
            catch(e){
              this.showError();
              console.error("Failed to create search results for the portal list: ", e);
            }

          },

          /**
          * Merges the SearchResults collection with the Usages collection
          */
          mergeSearchResults: function(searchResults){

            if(typeof searchResults == "undefined"){
              var searchResults = this.searchResults;
            }

            this.usagesCollection.mergeCollections(searchResults);

            //If in DataONE Plus Preview mode, total the portal count from Solr and use that as the portal totalUsage
            if( MetacatUI.appModel.get("dataonePlusPreviewMode") ){

              var portalQuotas = MetacatUI.appUserModel.getQuotas("portal");

              if( portalQuotas.length ){
                portalQuotas[0].set("totalUsage", this.usagesCollection.length);
              }

            }
          },

          /**
          * Shows the Usage info for each Portal in this view
          */
          showUsageInfo: function(){

            this.usagesCollection.each(function(usage){

              //Find the list item HTML element for this Usage
              var listItem = this.$("[data-seriesId='" + usage.get("instanceId") + "']");

              //If a list item is found, update it
              if( listItem.length ){

                //Disable the Edit button if the Usage status is "inactive"
                if( usage.get("status") == "inactive" ){
                  listItem.find(".edit.btn")
                          .attr("disabled", "disabled")
                          .popover({
                            trigger: "hover focus click",
                            placement: "top",
                            delay: {
                              show: 800
                            },
                            html: true,
                            content: "To edit this " + MetacatUI.appModel.get("portalTermSingular") + ", contact us at " +
                                     "<a href='mailto:" + MetacatUI.appModel.get("emailContact") + "'>" +
                                     MetacatUI.appModel.get("emailContact") + "</a>" +
                                     " to activate it. It may be deactivated because your " +
                                      MetacatUI.appModel.get("dataonePlusName") + " membership has ended."
                          });
                }

              }

            }, this);

            //Add a "Create" button to create a new portal, since we know the total Usage and
            // remaining Quota now.
            this.renderCreateButton();

          }

        });
    });