'use strict';

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

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

/**
 * A single-value metrics aggregation that calculates an approximate count of
 * distinct values. Values can be extracted either from specific fields in the
 * document or generated by a script.
 *
 * [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html)
 *
 * Aggregation that calculates an approximate count of distinct values.
 *
 * @example
 * const agg = esb.cardinalityAggregation('author_count', 'author');
 *
 * @example
 * const agg = esb.cardinalityAggregation('author_count').script(
 *     esb.script(
 *         'inline',
 *         "doc['author.first_name'].value + ' ' + doc['author.last_name'].value"
 *     ).lang('painless')
 * );
 *
 * @param {string} name The name which will be used to refer to this aggregation.
 * @param {string=} field The field to aggregate on
 *
 * @extends MetricsAggregationBase
 */
class CardinalityAggregation extends MetricsAggregationBase {
    // eslint-disable-next-line require-jsdoc
    constructor(name, field) {
        super(name, 'cardinality', field);
    }

    /**
     * @override
     * @throws {Error} This method cannot be called on CardinalityAggregation
     */
    format() {
        // Not 100% sure about this.
        console.log(`Please refer ${ES_REF_URL}`);
        throw new Error('format is not supported in CardinalityAggregation');
    }

    /**
     * The `precision_threshold` options allows to trade memory for accuracy,
     * and defines a unique count below which counts are expected to be close to accurate.
     *
     * @example
     * const agg = esb.cardinalityAggregation(
     *     'author_count',
     *     'author_hash'
     * ).precisionThreshold(100);
     *
     * @param {number} threshold The threshold value.
     * The maximum supported value is 40000, thresholds above this number
     * will have the same effect as a threshold of 40000. The default values is 3000.
     * @returns {CardinalityAggregation} returns `this` so that calls can be chained
     */
    precisionThreshold(threshold) {
        // TODO: Use validation and warning here
        this._aggsDef.precision_threshold = threshold;
        return this;
    }
}

module.exports = CardinalityAggregation;
