goog.module('grrUi.config.binariesListDirective');
goog.module.declareLegacyNamespace();


/**
 * Sorts binaries by comparing path lengths.
 *
 * By "path length" we understand number of components in a path. For example,
 * path `foo/bar/baz` has length 3. In case of path with equal lengths, paths
 * are compared using the default (lexicographical) comparison.
 *
 * Note that returned array has some extra fields containing path information.
 *
 * @param {Array<Object>} binaries
 * @return {!Array<Object>}
 */
exports.sortBinaries = function(binaries) {
  return binaries
      .map(function(b) {
        var newB = angular.copy(b);
        var pathComponents = newB['value']['path']['value'].split('/');
        newB['pathLen'] = pathComponents.length;
        newB['baseName'] = pathComponents.pop();
        newB['dirName'] = pathComponents.join('/');

        return newB;
      })
      .sort(function(a, b) {
        if (a['pathLen'] !== b['pathLen']) {
          return b['pathLen'] - a['pathLen'];
        }

        return a['value']['path']['value'].localeCompare(
            b['value']['path']['value']);
      });
};
var sortBinaries = exports.sortBinaries;


/**
 * Controller for BinariesListDirective.
 * @unrestricted
 */
const BinariesListController = class {
  /**
   * @param {!angular.Scope} $scope
   * @param {!grrUi.core.apiService.ApiService} grrApiService
   * @ngInject
   */
  constructor($scope, grrApiService) {
    /** @private {!angular.Scope} */
    this.scope_ = $scope;

    /** @private {!grrUi.core.apiService.ApiService} */
    this.grrApiService_ = grrApiService;

    /** @type {Array<Object>|undefined} */
    this.binaries;

    this.scope_.$watchGroup(
        ['binaries', 'binaryType'], this.onBinariesChange_.bind(this));
  }

  /**
   * @private
   */
  onBinariesChange_() {
    this.binaries = [];
    if (angular.isDefined(this.scope_['binaries'])) {
      var filteredBinaries = this.scope_['binaries'].filter(function(b) {
        return b['value']['type']['value'] === this.scope_['typeFilter'];
      }.bind(this));
      this.binaries = sortBinaries(filteredBinaries);
    }
  }

  /**
   * Handler for binary list click action.
   *
   * @param {Object} binary
   */
  onBinaryClicked(binary) {
    var url = '/config/binaries-blobs/' + binary['value']['type']['value'] +
        '/' + binary['value']['path']['value'];
    this.grrApiService_.downloadFile(url);
  }
};



/**
 * BinariesListDirective definition.
 * @return {angular.Directive} Directive definition object.
 */
exports.BinariesListDirective = function() {
  return {
    restrict: 'E',
    scope: {binaries: '=', typeFilter: '@'},
    templateUrl: '/static/angular-components/config/binaries-list.html',
    controller: BinariesListController,
    controllerAs: 'controller'
  };
};


/**
 * Name of the directive in Angular.
 *
 * @const
 * @export
 */
exports.BinariesListDirective.directive_name = 'grrBinariesList';
