'use strict';

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

const { Query } = require('../../core');

/**
 * The `percolate` query can be used to match queries stored in an index.
 * The `percolate` query itself contains the document that will be used
 * as query to match with the stored queries.
 *
 * [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-percolate-query.html)
 *
 * @example
 * const percolateQry = bob.percolateQuery('query', 'doctype')
 *     .document({ message: 'A new bonsai tree in the office' });
 *
 * const percolateQry = bob.percolateQuery()
 *     .field('query')
 *     .documentType('doctype')
 *     .index('my-index')
 *     .type('message')
 *     .id('1')
 *     .version(1);
 *
 * @param {string} field The field of type `percolator` and that holds the indexed queries.
 * @param {string} docType The type / mapping of the document being percolated.
 *
 * @extends Query
 */
class PercolateQuery extends Query {
    // eslint-disable-next-line require-jsdoc
    constructor(field, docType) {
        super('percolate');

        if (!isNil(field)) this._queryOpts.field = field;
        if (!isNil(docType)) this._queryOpts.document_type = docType;
    }

    /**
     * Sets the field of type `percolator` and that holds the indexed queries.
     *
     * @param {string} field The field of type `percolator` and that holds the indexed queries.
     * @returns {PercolateQuery} returns `this` so that calls can be chained.
     */
    field(field) {
        this._queryOpts.field = field;
        return this;
    }

    /**
     * Sets the type / mapping of the document being percolated.
     *
     * @param {string} docType The type / mapping of the document being percolated.
     * @returns {PercolateQuery} returns `this` so that calls can be chained.
     */
    documentType(docType) {
        this._queryOpts.document_type = docType;
        return this;
    }

    /**
     * Sets the source of the document being percolated.
     * Instead of specifying the source of the document being percolated,
     * the source can also be retrieved from an already stored document.
     *
     * @param {Object} doc The source of the document being percolated.
     * @returns {PercolateQuery} returns `this` so that calls can be chained.
     */
    document(doc) {
        this._queryOpts.document = doc;
        return this;
    }

    /**
     * Sets the index the document resides in. This is a required parameter if `document`
     * is not specified.
     *
     * @param {string} index The index the document resides in.
     * @returns {PercolateQuery} returns `this` so that calls can be chained.
     */
    index(index) {
        this._queryOpts.index = index;
        return this;
    }

    /**
     * Sets the type of the document to fetch. This is a required parameter if `document`
     * is not specified.
     *
     * @param {string} type The type of the document to fetch.
     * @returns {PercolateQuery} returns `this` so that calls can be chained.
     */
    type(type) {
        this._queryOpts.type = type;
        return this;
    }

    /**
     * Sets the id of the document to fetch. This is a required parameter if `document`
     * is not specified.
     *
     * @param {string} id The id of the document to fetch.
     * @returns {PercolateQuery} returns `this` so that calls can be chained.
     */
    id(id) {
        this._queryOpts.id = id;
        return this;
    }

    /**
     * Sets the routing to be used to fetch document to percolate. Optional.
     *
     * @param {string} routing The routing to be used to fetch document to percolate.
     * @returns {PercolateQuery} returns `this` so that calls can be chained.
     */
    routing(routing) {
        this._queryOpts.routing = routing;
        return this;
    }

    /**
     * Sets the preference to be used to fetch document to percolate. Optional.
     *
     * @param {string} preference The preference to be used to fetch document to percolate.
     * @returns {PercolateQuery} returns `this` so that calls can be chained.
     */
    preference(preference) {
        this._queryOpts.preference = preference;
        return this;
    }

    /**
     * Sets the expected version of the document to be fetched. Optional.
     * If the version does not match, the search request will fail
     * with a version conflict error.
     *
     * @param {string} version The expected version of the document to be fetched.
     * @returns {PercolateQuery} returns `this` so that calls can be chained.
     */
    version(version) {
        this._queryOpts.version = version;
        return this;
    }
}

module.exports = PercolateQuery;

@@ -759,32 +759,33 @@
 * @param %7Bstring
+=
 %7D field The fiel
@@ -852,32 +852,33 @@
 * @param %7Bstring
+=
 %7D docType The ty

Annotate params to constructor as optional