<commit_before>define([
  'angular',
  'lodash',
  'kbn',
  './queryCtrl',
],
function (angular, _, kbn) {
  'use strict';

  var module = angular.module('grafana.services');

  module.factory('ZabbixAPIDatasource', function($q, backendSrv, templateSrv) {

    function ZabbixAPIDatasource(datasource) {
      this.name             = datasource.name;
      this.url              = datasource.url;

      // TODO: fix passing username and password from config.html
      this.username         = datasource.meta.username;
      this.password         = datasource.meta.password;

      // Limit metrics per panel
      this.limitmetrics = datasource.meta.limitmetrics || 20;

      // For testing
      this.ds = datasource;
    }


    ZabbixAPIDatasource.prototype.query = function(options) {
      // get from & to in seconds
      var from = Math.ceil(kbn.parseDate(options.range.from).getTime() / 1000);
      var to = Math.ceil(kbn.parseDate(options.range.to).getTime() / 1000);

      // Create request for each target
      var promises = _.map(options.targets, function(target) {
        // Remove undefined and hidden targets
        if (target.hide || !target.item) {
          return [];
        }

        if (!target.item.templated) {

          // Perform request and then handle result
          var item = [target.item];
          var alias = [{
            itemid: target.item.itemid,
            key_: '',
            name: target.alias
          }];
          return this.performTimeSeriesQuery(item, from, to).then(_.partial(
            this.handleHistoryResponse, alias));
        } else {
          // Handle templated target

          var itemname = templateSrv.replace(target.item.name);
          var hostname = templateSrv.replace(target.host.name);

          // Extract zabbix hosts
          var host_pattern = /([\w\.\s]+)/g;
          var hosts = hostname.match(host_pattern);

          // Extract item names
          var delete_hostname_pattern = /(?:\[[\w\.]+\]\:\s)/g;
          var itemname_pattern = /([^{},]+)/g;
          // Remove hostnames from item name
          // [hostname]: itemname --> itemname
          var itemnames = itemname.replace(delete_hostname_pattern, '').match(itemname_pattern);
          //var aliases = itemname.match(itemname_pattern);

          if (itemnames && (itemnames.length < this.limitmetrics)) {
            // Find items by item names and perform queries
            var self = this;
            // TODO: do one query.
            if (hosts.length > 1) {
              // Select the host that the item belongs for multiple hosts request
              var selectHosts = true;
            }
            return this.findZabbixItem(hosts, itemnames, selectHosts).then(function (items) {
              items = _.flatten(items);
              return self.performTimeSeriesQuery(items, from, to)
                .then(_.partial(self.handleHistoryResponse, items));
              });
          } else {
            return [];
          }
        }
      }, this);

      return $q.all(_.flatten(promises)).then(function (results) {
        return { data: _.flatten(results) };
      });
    };


    /**
     * Perform time series query to Zabbix API
     *
     * @param items: array of zabbix api item objects
     */
    ZabbixAPIDatasource.prototype.performTimeSeriesQuery = function(items, start, end) {
      // Group items by value type
      var grouped_items = _.groupBy(items, 'value_type');

      // Perform request for each value type
      return $q.all(_.map(grouped_items, function (items, value_type) {
        var itemids = _.map(items, 'itemid');
        var params = {
          output: 'extend',
          history: value_type,
          itemids: itemids,
          sortfield: 'clock',
          sortorder: 'ASC',
          time_from: start
        };

        // Relative queries (e.g. last hour) don't include an end time
        if (end) {
          params.time_till = end;
        }

        return this.performZabbixAPIRequest('history.get', params);
      }, this)).then(function (results) {
        return _.flatten(results);
      });
    };


    // Convert Zabbix API data to Grafana format
    ZabbixAPIDatasource.prototype.handleHistoryResponse = function(items, response) {
      /**
       * Response should be in the format:
       * data: [
       *          {
       *             target: "Metric name",
       *             datapoints: [[<value>, <unixtime>], ...]
       *          },
       *          {
       *             target: "Metric name",
       *             datapoints: [[<value>, <unixtime>], ...]
       *          },
       *       ]
       */

      // Group items and history by itemid
      var indexed_items = _.indexBy(items, 'itemid');
      var grouped_history = _.groupBy(response, 'itemid');

      return $q.when(_.map(grouped_history, function (history, itemid) {
        var item = indexed_items[itemid];
        var series = {
          // TODO: remove []
          target: (item.hosts ? '['+item.hosts[0].name+']: ' : '') + expandItemName(item),
          datapoints: _.map(history, function (p) {
            // Value must be a number for properly work<commit_msg>Removed [] from aliases for templated graphs.<commit_after>define([
  'angular',
  'lodash',
  'kbn',
  './queryCtrl',
],
function (angular, _, kbn) {
  'use strict';

  var module = angular.module('grafana.services');

  module.factory('ZabbixAPIDatasource', function($q, backendSrv, templateSrv) {

    function ZabbixAPIDatasource(datasource) {
      this.name             = datasource.name;
      this.url              = datasource.url;

      // TODO: fix passing username and password from config.html
      this.username         = datasource.meta.username;
      this.password         = <PASSWORD>;

      // Limit metrics per panel
      this.limitmetrics = datasource.meta.limitmetrics || 20;

      // For testing
      this.ds = datasource;
    }


    ZabbixAPIDatasource.prototype.query = function(options) {
      // get from & to in seconds
      var from = Math.ceil(kbn.parseDate(options.range.from).getTime() / 1000);
      var to = Math.ceil(kbn.parseDate(options.range.to).getTime() / 1000);

      // Create request for each target
      var promises = _.map(options.targets, function(target) {
        // Remove undefined and hidden targets
        if (target.hide || !target.item) {
          return [];
        }

        if (!target.item.templated) {

          // Perform request and then handle result
          var item = [target.item];
          var alias = [{
            itemid: target.item.itemid,
            key_: '',
            name: target.alias
          }];
          return this.performTimeSeriesQuery(item, from, to).then(_.partial(
            this.handleHistoryResponse, alias));
        } else {
          // Handle templated target

          var itemname = templateSrv.replace(target.item.name);
          var hostname = templateSrv.replace(target.host.name);

          // Extract zabbix hosts
          var host_pattern = /([\w\.\s]+)/g;
          var hosts = hostname.match(host_pattern);

          // Extract item names
          var delete_hostname_pattern = /(?:\[[\w\.]+\]\:\s)/g;
          var itemname_pattern = /([^{},]+)/g;
          // Remove hostnames from item name
          // [hostname]: itemname --> itemname
          var itemnames = itemname.replace(delete_hostname_pattern, '').match(itemname_pattern);
          //var aliases = itemname.match(itemname_pattern);

          if (itemnames && (itemnames.length < this.limitmetrics)) {
            // Find items by item names and perform queries
            var self = this;
            if (hosts.length > 1) {
              // Select the host that the item belongs for multiple hosts request
              var selectHosts = true;
            }
            return this.findZabbixItem(hosts, itemnames, selectHosts).then(function (items) {
              items = _.flatten(items);
              return self.performTimeSeriesQuery(items, from, to)
                .then(_.partial(self.handleHistoryResponse, items));
              });
          } else {
            return [];
          }
        }
      }, this);

      return $q.all(_.flatten(promises)).then(function (results) {
        return { data: _.flatten(results) };
      });
    };


    /**
     * Perform time series query to Zabbix API
     *
     * @param items: array of zabbix api item objects
     */
    ZabbixAPIDatasource.prototype.performTimeSeriesQuery = function(items, start, end) {
      // Group items by value type
      var grouped_items = _.groupBy(items, 'value_type');

      // Perform request for each value type
      return $q.all(_.map(grouped_items, function (items, value_type) {
        var itemids = _.map(items, 'itemid');
        var params = {
          output: 'extend',
          history: value_type,
          itemids: itemids,
          sortfield: 'clock',
          sortorder: 'ASC',
          time_from: start
        };

        // Relative queries (e.g. last hour) don't include an end time
        if (end) {
          params.time_till = end;
        }

        return this.performZabbixAPIRequest('history.get', params);
      }, this)).then(function (results) {
        return _.flatten(results);
      });
    };


    // Convert Zabbix API data to Grafana format
    ZabbixAPIDatasource.prototype.handleHistoryResponse = function(items, response) {
      /**
       * Response should be in the format:
       * data: [
       *          {
       *             target: "Metric name",
       *             datapoints: [[<value>, <unixtime>], ...]
       *          },
       *          {
       *             target: "Metric name",
       *             datapoints: [[<value>, <unixtime>], ...]
       *          },
       *       ]
       */

      // Group items and history by itemid
      var indexed_items = _.indexBy(items, 'itemid');
      var grouped_history = _.groupBy(response, 'itemid');

      return $q.when(_.map(grouped_history, function (history, itemid) {
        var item = indexed_items[itemid];
        var series = {
          target: (item.hosts ? item.hosts[0].name+': ' : '') + expandItemName(item),
          datapoints: _.map(history, function (p) {
            // Value must be a number for properly work
{'fraction_non_alphanumeric': 0.12298328663897208, 'fraction_numerical': 0.0023186165587865907, 'mean_word_length': 1.8502202643171806, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5732463', 'n_tokens_mistral': 2992, 'n_tokens_neox': 2877, 'n_words': 704}