'use strict';

var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

var _createClass2 = require('babel-runtime/helpers/createClass');

var _createClass3 = _interopRequireDefault(_createClass2);

var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');

var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);

var _inherits2 = require('babel-runtime/helpers/inherits');

var _inherits3 = _interopRequireDefault(_inherits2);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var isNil = require('lodash.isnil');

var _require = require('../../core'),
    checkType = _require.util.checkType;

var MetricsAggregationBase = require('./metrics-aggregation-base');

var ES_REF_URL = 'https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-percentile-rank-aggregation.html';

/**
 * A multi-value metrics aggregation that calculates one or more percentile ranks
 * over numeric values extracted from the aggregated documents. These values can
 * be extracted either from specific numeric fields in the documents, or be
 * generated by a provided script.
 *
 * [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-percentile-rank-aggregation.html)
 *
 * Aggregation that calculates one or more percentiles ranks over numeric values
 * extracted from the aggregated documents.
 *
 * @example
 * const agg = esb.percentileRanksAggregation(
 *     'load_time_outlier',
 *     'load_time',
 *     [15, 30]
 * );
 *
 * @example
 * // Convert load time from mills to seconds on-the-fly using script
 * const agg = esb.percentileRanksAggregation('load_time_outlier')
 *     .values([3, 5])
 *     .script(
 *         esb.script('inline', "doc['load_time'].value / params.timeUnit")
 *             .lang('painless')
 *             .params({ timeUnit: 1000 })
 *     );
 *
 * @param {string} name The name which will be used to refer to this aggregation.
 * @param {string=} field The field to aggregate on. It must be a numeric field
 * @param {Array=} values Values to compute percentiles from.
 *
 * @throws {TypeError} If `values` is not an instance of Array
 *
 * @extends MetricsAggregationBase
 */

var PercentileRanksAggregation = function (_MetricsAggregationBa) {
    (0, _inherits3.default)(PercentileRanksAggregation, _MetricsAggregationBa);

    // eslint-disable-next-line require-jsdoc
    function PercentileRanksAggregation(name, field, values) {
        (0, _classCallCheck3.default)(this, PercentileRanksAggregation);

        var _this = (0, _possibleConstructorReturn3.default)(this, (PercentileRanksAggregation.__proto__ || Object.getPrototypeOf(PercentileRanksAggregation)).call(this, name, 'percentile_ranks', field));

        if (!isNil(values)) _this.values(values);
        return _this;
    }

    /**
     * @override
     * @throws {Error} This method cannot be called on PercentileRanksAggregation
     */


    (0, _createClass3.default)(PercentileRanksAggregation, [{
        key: 'format',
        value: function format() {
            // Not 100% sure about this.
            console.log('Please refer ' + ES_REF_URL);
            throw new Error('format is not supported in PercentileRanksAggregation');
        }

        /**
         * Enable the response to be returned as a keyed object where the key is the
         * bucket interval.
         *
         * @example
         * // Return the ranges as an array rather than a hash
         * const agg = esb.percentileRanksAggregation('balance_outlier', 'balance')
         *     .values([25000, 50000])
         *     .keyed(false);
         *
         * @param {boolean} keyed To enable keyed response or not.
         * @returns {PercentilesRanksAggregation} returns `this` so that calls can be chained
         */

    }, {
        key: 'keyed',
        value: function keyed(_keyed) {
            this._aggsDef.keyed = _keyed;
            return this;
        }

        /**
         * Specifies the values to compute percentiles from.
         *
         * @param {Array<number>} values Values to compute percentiles from.
         * @returns {PercentileRanksAggregation} returns `this` so that calls can be chained
         * @throws {TypeError} If `values` is not an instance of Array
         */

    }, {
        key: 'values',
        value: function values(_values) {
            checkType(_values, Array);
            this._aggsDef.values = _values;
            return this;
        }

        /**
         * Compression controls memory usage and approximation error. The compression
         * value limits the maximum number of nodes to 100 * compression. By
         * increasing the compression value, you can increase the accuracy of your
         * percentiles at the cost of more memory. Larger compression values also make
         * the algorithm slower since the underlying tree data structure grows in
         * size, resulting in more expensive operations. The default compression
         * value is 100.
         *
         * @param {number} compression Parameter to balance memory utilization with estimation accuracy.
         * @returns {PercentileRanksAggregation} returns `this` so that calls can be chained
         */

    }, {
        key: 'tdigest',
        value: function tdigest(compression) {
            this._aggsDef.tdigest = { compression: compression };
            return this;
        }

        /**
         * Compression controls memory usage and approximation error. The compression
         * value limits the maximum number of nodes to 100 * compression. By
         * increasing the compression value, you can increase the accuracy of your
         * percentiles at the cost of more memory. Larger compression values also make
         * the algorithm slower since the underlying tree data structure grows in
         * size, resulting in more expensive operations. The default compression
         * value is 100.
         *
         * Alias for `tdigest`
         *
         * @param {number} compression Parameter to balance memory utilization with estimation accuracy.
         * @returns {PercentileRanksAggregation} returns `this` so that calls can be chained
         */

    }, {
        key: 'compression',
        value: function compression(_compression) {
            return this.tdigest(_compression);
        }

        /**
         * HDR Histogram (High Dynamic Range Histogram) is an alternative implementation
         * that can be useful when calculating percentiles for latency measurements
         * as it can be faster than the t-digest implementation
         * with the trade-off of a larger memory footprint.
         *
         * The HDR Histogram can be used by specifying the method parameter in the request.
         *
         * @example
         * const agg = esb.percentileRanksAggregation(
         *     'load_time_outlier',
         *     'load_time',
         *     [15, 30]
         * ).hdr(3);
         *
         * @param {number} numberOfSigDigits The resolution of values
         * for the histogram in number of significant digits
         * @returns {PercentileRanksAggregation} returns `this` so that calls can be chained
         */

    }, {
        key: 'hdr',
        value: function hdr(numberOfSigDigits) {
            this._aggsDef.hdr = {
                number_of_significant_value_digits: numberOfSigDigits
            };
            return this;
        }
    }]);
    return PercentileRanksAggregation;
}(MetricsAggregationBase);

module.exports = PercentileRanksAggregation;