<?php

declare(strict_types=1);

/**
 * Copyright OpenSearch Contributors
 * SPDX-License-Identifier: Apache-2.0
 *
 * OpenSearch PHP client
 *
 * @link      https://github.com/opensearch-project/opensearch-php/
 * @copyright Copyright (c) Elasticsearch B.V (https://www.elastic.co)
 * @license   http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 * @license   https://www.gnu.org/licenses/lgpl-2.1.html GNU Lesser General Public License, Version 2.1
 *
 * Licensed to Elasticsearch B.V under one or more agreements.
 * Elasticsearch B.V licenses this file to you under the Apache 2.0 License or
 * the GNU Lesser General Public License, Version 2.1, at your option.
 * See the LICENSE file in the project root for more information.
 */

namespace OpenSearch;

use OpenSearch\Endpoints\AbstractEndpoint;
use OpenSearch\Namespaces\BooleanRequestWrapper;
use OpenSearch\Namespaces\NamespaceBuilderInterface;
use OpenSearch\Namespaces\AsyncSearchNamespace;
use OpenSearch\Namespaces\AsynchronousSearchNamespace;
use OpenSearch\Namespaces\CatNamespace;
use OpenSearch\Namespaces\ClusterNamespace;
use OpenSearch\Namespaces\DanglingIndicesNamespace;
use OpenSearch\Namespaces\DataFrameTransformDeprecatedNamespace;
use OpenSearch\Namespaces\FlowFrameworkNamespace;
use OpenSearch\Namespaces\GeospatialNamespace;
use OpenSearch\Namespaces\IndicesNamespace;
use OpenSearch\Namespaces\IngestNamespace;
use OpenSearch\Namespaces\IngestionNamespace;
use OpenSearch\Namespaces\InsightsNamespace;
use OpenSearch\Namespaces\IsmNamespace;
use OpenSearch\Namespaces\KnnNamespace;
use OpenSearch\Namespaces\ListNamespace;
use OpenSearch\Namespaces\LtrNamespace;
use OpenSearch\Namespaces\MlNamespace;
use OpenSearch\Namespaces\MonitoringNamespace;
use OpenSearch\Namespaces\NeuralNamespace;
use OpenSearch\Namespaces\NodesNamespace;
use OpenSearch\Namespaces\NotificationsNamespace;
use OpenSearch\Namespaces\ObservabilityNamespace;
use OpenSearch\Namespaces\PplNamespace;
use OpenSearch\Namespaces\QueryNamespace;
use OpenSearch\Namespaces\RemoteStoreNamespace;
use OpenSearch\Namespaces\ReplicationNamespace;
use OpenSearch\Namespaces\RollupsNamespace;
use OpenSearch\Namespaces\SearchPipelineNamespace;
use OpenSearch\Namespaces\SearchRelevanceNamespace;
use OpenSearch\Namespaces\SearchableSnapshotsNamespace;
use OpenSearch\Namespaces\SecurityNamespace;
use OpenSearch\Namespaces\SecurityAnalyticsNamespace;
use OpenSearch\Namespaces\SmNamespace;
use OpenSearch\Namespaces\SnapshotNamespace;
use OpenSearch\Namespaces\SqlNamespace;
use OpenSearch\Namespaces\SslNamespace;
use OpenSearch\Namespaces\TasksNamespace;
use OpenSearch\Namespaces\TransformsNamespace;
use OpenSearch\Namespaces\UbiNamespace;
use OpenSearch\Namespaces\WlmNamespace;
use OpenSearch\Endpoints\Bulk;
use OpenSearch\Endpoints\BulkStream;
use OpenSearch\Endpoints\ClearScroll;
use OpenSearch\Endpoints\Count;
use OpenSearch\Endpoints\Create;
use OpenSearch\Endpoints\CreatePit;
use OpenSearch\Endpoints\Delete;
use OpenSearch\Endpoints\DeleteAllPits;
use OpenSearch\Endpoints\DeleteByQuery;
use OpenSearch\Endpoints\DeleteByQueryRethrottle;
use OpenSearch\Endpoints\DeletePit;
use OpenSearch\Endpoints\DeleteScript;
use OpenSearch\Endpoints\Exists;
use OpenSearch\Endpoints\ExistsSource;
use OpenSearch\Endpoints\Explain;
use OpenSearch\Endpoints\FieldCaps;
use OpenSearch\Endpoints\Get;
use OpenSearch\Endpoints\GetAllPits;
use OpenSearch\Endpoints\GetScript;
use OpenSearch\Endpoints\GetScriptContext;
use OpenSearch\Endpoints\GetScriptLanguages;
use OpenSearch\Endpoints\GetSource;
use OpenSearch\Endpoints\Index;
use OpenSearch\Endpoints\Info;
use OpenSearch\Endpoints\MTermVectors;
use OpenSearch\Endpoints\Mget;
use OpenSearch\Endpoints\Msearch;
use OpenSearch\Endpoints\MsearchTemplate;
use OpenSearch\Endpoints\Ping;
use OpenSearch\Endpoints\PutScript;
use OpenSearch\Endpoints\RankEval;
use OpenSearch\Endpoints\Reindex;
use OpenSearch\Endpoints\ReindexRethrottle;
use OpenSearch\Endpoints\RenderSearchTemplate;
use OpenSearch\Endpoints\ScriptsPainlessExecute;
use OpenSearch\Endpoints\Scroll;
use OpenSearch\Endpoints\Search;
use OpenSearch\Endpoints\SearchShards;
use OpenSearch\Endpoints\SearchTemplate;
use OpenSearch\Endpoints\TermVectors;
use OpenSearch\Endpoints\Update;
use OpenSearch\Endpoints\UpdateByQuery;
use OpenSearch\Endpoints\UpdateByQueryRethrottle;

/**
 * Class Client
 *
 * NOTE: This file is autogenerated using util/GenerateEndpoints.php
 */
class Client
{
    public const VERSION = '2.5.1';

    /**
     * @var Transport
     *
     * @deprecated in 2.4.0 and will be removed in 3.0.0.
     */
    public $transport;

    private TransportInterface $httpTransport;

    /**
     * @var array
     */
    protected $params;

    private EndpointFactoryInterface $endpointFactory;

    /**
     * @var callable
     *
     * @deprecated in 2.4.0 and will be removed in 3.0.0.
     */
    protected $endpoints;

    /**
     * @var NamespaceBuilderInterface[]
     */
    protected $registeredNamespaces = [];

    /**
     * @var AsyncSearchNamespace
     *
     * @deprecated in 2.4.2 and will be removed in 3.0.0.
     */
    protected $asyncSearch;

    /**
     * @var AsynchronousSearchNamespace
     */
    protected $asynchronousSearch;

    /**
     * @var CatNamespace
     */
    protected $cat;

    /**
     * @var ClusterNamespace
     */
    protected $cluster;

    /**
     * @var DanglingIndicesNamespace
     */
    protected $danglingIndices;

    /**
     * @var DataFrameTransformDeprecatedNamespace
     *
     * @deprecated in 2.4.2 and will be removed in 3.0.0.
     */
    protected $dataFrameTransformDeprecated;

    /**
     * @var FlowFrameworkNamespace
     */
    protected $flowFramework;

    /**
     * @var GeospatialNamespace
     */
    protected $geospatial;

    /**
     * @var IndicesNamespace
     */
    protected $indices;

    /**
     * @var IngestNamespace
     */
    protected $ingest;

    /**
     * @var IngestionNamespace
     */
    protected $ingestion;

    /**
     * @var InsightsNamespace
     */
    protected $insights;

    /**
     * @var IsmNamespace
     */
    protected $ism;

    /**
     * @var KnnNamespace
     */
    protected $knn;

    /**
     * @var ListNamespace
     */
    protected $list;

    /**
     * @var LtrNamespace
     */
    protected $ltr;

    /**
     * @var MlNamespace
     */
    protected $ml;

    /**
     * @var MonitoringNamespace
     *
     * @deprecated in 2.4.2 and will be removed in 3.0.0.
     */
    protected $monitoring;

    /**
     * @var NeuralNamespace
     */
    protected $neural;

    /**
     * @var NodesNamespace
     */
    protected $nodes;

    /**
     * @var NotificationsNamespace
     */
    protected $notifications;

    /**
     * @var ObservabilityNamespace
     */
    protected $observability;

    /**
     * @var PplNamespace
     */
    protected $ppl;

    /**
     * @var QueryNamespace
     */
    protected $query;

    /**
     * @var RemoteStoreNamespace
     */
    protected $remoteStore;

    /**
     * @var ReplicationNamespace
     */
    protected $replication;

    /**
     * @var RollupsNamespace
     */
    protected $rollups;

    /**
     * @var SearchPipelineNamespace
     */
    protected $searchPipeline;

    /**
     * @var SearchRelevanceNamespace
     */
    protected $searchRelevance;

    /**
     * @var SearchableSnapshotsNamespace
     *
     * @deprecated in 2.4.2 and will be removed in 3.0.0.
     */
    protected $searchableSnapshots;

    /**
     * @var SecurityNamespace
     */
    protected $security;

    /**
     * @var SecurityAnalyticsNamespace
     */
    protected $securityAnalytics;

    /**
     * @var SmNamespace
     */
    protected $sm;

    /**
     * @var SnapshotNamespace
     */
    protected $snapshot;

    /**
     * @var SqlNamespace
     */
    protected $sql;

    /**
     * @var SslNamespace
     *
     * @deprecated in 2.4.2 and will be removed in 3.0.0.
     */
    protected $ssl;

    /**
     * @var TasksNamespace
     */
    protected $tasks;

    /**
     * @var TransformsNamespace
     */
    protected $transforms;

    /**
     * @var UbiNamespace
     */
    protected $ubi;

    /**
     * @var WlmNamespace
     */
    protected $wlm;

    /**
     * Client constructor
     *
     * @param TransportInterface|Transport $transport
     * @param callable|EndpointFactoryInterface|null $endpointFactory
     * @param NamespaceBuilderInterface[] $registeredNamespaces
     *
     * @phpstan-ignore parameter.deprecatedClass
     */
    public function __construct(
        TransportInterface|Transport $transport,
        callable|EndpointFactoryInterface|null $endpointFactory = null,
        array $registeredNamespaces = [],
    ) {
        if (!$transport instanceof TransportInterface) {
            @trigger_error('Passing an instance of \OpenSearch\Transport to ' . __METHOD__ . '() is deprecated in 2.4.0 and will be removed in 3.0.0. Pass an instance of \OpenSearch\TransportInterface instead.', E_USER_DEPRECATED);
            // @phpstan-ignore property.deprecated
            $this->transport = $transport;
            // @phpstan-ignore new.deprecated
            $this->httpTransport = new LegacyTransportWrapper($transport);
        } else {
            $this->httpTransport = $transport;
        }

        if (is_callable($endpointFactory)) {
            @trigger_error('Passing a callable as the $endpointFactory param in ' . __METHOD__ . ' is deprecated in 2.4.0 and will be removed in 3.0.0. Pass an instance of \OpenSearch\EndpointFactoryInterface instead.', E_USER_DEPRECATED);
            $endpoints = $endpointFactory;
            // @phpstan-ignore new.deprecated
            $endpointFactory = new LegacyEndpointFactory($endpointFactory);
        } else {
            if ($endpointFactory === null) {
                $endpointFactory = new EndpointFactory();
            }
            $endpoints = function ($c) use ($endpointFactory) {
                @trigger_error('The $endpoints property is deprecated in 2.4.0 and will be removed in 3.0.0.', E_USER_DEPRECATED);
                return $endpointFactory->getEndpoint('OpenSearch\\Endpoints\\' . $c);
            };
        }

        // @phpstan-ignore property.deprecated
        $this->endpoints = $endpoints;
        $this->endpointFactory = $endpointFactory;
        // @phpstan-ignore new.deprecated, property.deprecated
        $this->asyncSearch = new AsyncSearchNamespace($transport, $this->endpointFactory);
        $this->asynchronousSearch = new AsynchronousSearchNamespace($transport, $this->endpointFactory);
        $this->cat = new CatNamespace($transport, $this->endpointFactory);
        $this->cluster = new ClusterNamespace($transport, $this->endpointFactory);
        $this->danglingIndices = new DanglingIndicesNamespace($transport, $this->endpointFactory);
        // @phpstan-ignore new.deprecated, property.deprecated
        $this->dataFrameTransformDeprecated = new DataFrameTransformDeprecatedNamespace($transport, $this->endpointFactory);
        $this->flowFramework = new FlowFrameworkNamespace($transport, $this->endpointFactory);
        $this->geospatial = new GeospatialNamespace($transport, $this->endpointFactory);
        $this->indices = new IndicesNamespace($transport, $this->endpointFactory);
        $this->ingest = new IngestNamespace($transport, $this->endpointFactory);
        $this->ingestion = new IngestionNamespace($transport, $this->endpointFactory);
        $this->insights = new InsightsNamespace($transport, $this->endpointFactory);
        $this->ism = new IsmNamespace($transport, $this->endpointFactory);
        $this->knn = new KnnNamespace($transport, $this->endpointFactory);
        $this->list = new ListNamespace($transport, $this->endpointFactory);
        $this->ltr = new LtrNamespace($transport, $this->endpointFactory);
        $this->ml = new MlNamespace($transport, $this->endpointFactory);
        // @phpstan-ignore new.deprecated, property.deprecated
        $this->monitoring = new MonitoringNamespace($transport, $this->endpointFactory);
        $this->neural = new NeuralNamespace($transport, $this->endpointFactory);
        $this->nodes = new NodesNamespace($transport, $this->endpointFactory);
        $this->notifications = new NotificationsNamespace($transport, $this->endpointFactory);
        $this->observability = new ObservabilityNamespace($transport, $this->endpointFactory);
        $this->ppl = new PplNamespace($transport, $this->endpointFactory);
        $this->query = new QueryNamespace($transport, $this->endpointFactory);
        $this->remoteStore = new RemoteStoreNamespace($transport, $this->endpointFactory);
        $this->replication = new ReplicationNamespace($transport, $this->endpointFactory);
        $this->rollups = new RollupsNamespace($transport, $this->endpointFactory);
        $this->searchPipeline = new SearchPipelineNamespace($transport, $this->endpointFactory);
        $this->searchRelevance = new SearchRelevanceNamespace($transport, $this->endpointFactory);
        // @phpstan-ignore new.deprecated, property.deprecated
        $this->searchableSnapshots = new SearchableSnapshotsNamespace($transport, $this->endpointFactory);
        $this->security = new SecurityNamespace($transport, $this->endpointFactory);
        $this->securityAnalytics = new SecurityAnalyticsNamespace($transport, $this->endpointFactory);
        $this->sm = new SmNamespace($transport, $this->endpointFactory);
        $this->snapshot = new SnapshotNamespace($transport, $this->endpointFactory);
        $this->sql = new SqlNamespace($transport, $this->endpointFactory);
        // @phpstan-ignore new.deprecated, property.deprecated
        $this->ssl = new SslNamespace($transport, $this->endpointFactory);
        $this->tasks = new TasksNamespace($transport, $this->endpointFactory);
        $this->transforms = new TransformsNamespace($transport, $this->endpointFactory);
        $this->ubi = new UbiNamespace($transport, $this->endpointFactory);
        $this->wlm = new WlmNamespace($transport, $this->endpointFactory);

        $this->registeredNamespaces = $registeredNamespaces;
    }

    /**
     * Allows to perform multiple index/update/delete operations in a single request.
     *
     * $params['index']                  = (string) Name of the data stream, index, or index alias to perform bulk actions on.
     * $params['_source']                = (any) `true` or `false` to return the `_source` field or not, or a list of fields to return.
     * $params['_source_excludes']       = (any) A comma-separated list of source fields to exclude from the response.
     * $params['_source_includes']       = (any) A comma-separated list of source fields to include in the response.
     * $params['pipeline']               = (string) ID of the pipeline to use to preprocess incoming documents. If the index has a default ingest pipeline specified, then setting the value to `_none` disables the default ingest pipeline for this request. If a final pipeline is configured it will always run, regardless of the value of this parameter.
     * $params['refresh']                = (any) If `true`, OpenSearch refreshes the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` do nothing with refreshes. Valid values: `true`, `false`, `wait_for`.
     * $params['require_alias']          = (boolean) If `true`, the request's actions must target an index alias. (Default = false)
     * $params['routing']                = (string) A custom value used to route operations to a specific shard.
     * $params['timeout']                = (string) Period each action waits for the following operations: automatic index creation, dynamic mapping updates, waiting for active shards.
     * $params['wait_for_active_shards'] = (any) The number of shard copies that must be active before proceeding with the operation. Set to all or any positive integer up to the total number of shards in the index (`number_of_replicas+1`).
     * $params['pretty']                 = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                  = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']            = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                 = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']            = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']                   = (array) The operation definition and data (action-data pairs), separated by newlines (Required)
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function bulk(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(Bulk::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Allows to perform multiple index/update/delete operations using request response streaming.
     *
     * $params['index']                  = (string) Name of the data stream, index, or index alias to perform bulk actions on.
     * $params['_source']                = (any) `true` or `false` to return the `_source` field or not, or a list of fields to return.
     * $params['_source_excludes']       = (any) A comma-separated list of source fields to exclude from the response.
     * $params['_source_includes']       = (any) A comma-separated list of source fields to include in the response.
     * $params['batch_interval']         = (string) Specifies for how long bulk operations should be accumulated into a batch before sending the batch to data nodes.
     * $params['batch_size']             = (integer) Specifies how many bulk operations should be accumulated into a batch before sending the batch to data nodes.
     * $params['pipeline']               = (string) ID of the pipeline to use to preprocess incoming documents. If the index has a default ingest pipeline specified, then setting the value to `_none` disables the default ingest pipeline for this request. If a final pipeline is configured it will always run, regardless of the value of this parameter.
     * $params['refresh']                = (any) If `true`, OpenSearch refreshes the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` do nothing with refreshes. Valid values: `true`, `false`, `wait_for`.
     * $params['require_alias']          = (boolean) If `true`, the request's actions must target an index alias. (Default = false)
     * $params['routing']                = (any) A custom value used to route operations to a specific shard.
     * $params['timeout']                = (string) Period each action waits for the following operations: automatic index creation, dynamic mapping updates, waiting for active shards.
     * $params['wait_for_active_shards'] = (any) The number of shard copies that must be active before proceeding with the operation. Set to all or any positive integer up to the total number of shards in the index (`number_of_replicas+1`).
     * $params['pretty']                 = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                  = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']            = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                 = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']            = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']                   = (array) The operation definition and data (action-data pairs), separated by newlines (Required)
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function bulkStream(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(BulkStream::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Explicitly clears the search context for a scroll.
     *
     * $params['scroll_id']   = DEPRECATED (array) A comma-separated list of scroll IDs to clear. To clear all scroll IDs, use `_all`.
     * $params['pretty']      = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']       = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace'] = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']      = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path'] = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']        = (array) A comma-separated list of scroll IDs to clear if none was specified using the `scroll_id` parameter
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function clearScroll(array $params = [])
    {
        $scroll_id = $this->extractArgument($params, 'scroll_id');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(ClearScroll::class);
        $endpoint->setParams($params);
        $endpoint->setScrollId($scroll_id);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Returns number of documents matching a query.
     *
     * $params['index']              = (array) A comma-separated list of data streams, indexes, and aliases to search. Supports wildcards (`*`). To search all data streams and indexes, omit this parameter or use `*` or `_all`.
     * $params['allow_no_indices']   = (boolean) If `false`, the request returns an error if any wildcard expression, index alias, or `_all` value targets only missing or closed indexes. This behavior applies even if the request targets other open indexes.
     * $params['analyze_wildcard']   = (boolean) If `true`, wildcard and prefix queries are analyzed. This parameter can only be used when the `q` query string parameter is specified. (Default = false)
     * $params['analyzer']           = (string) Analyzer to use for the query string. This parameter can only be used when the `q` query string parameter is specified.
     * $params['default_operator']   = (enum) The default operator for query string query: `AND` or `OR`. This parameter can only be used when the `q` query string parameter is specified. (Options = and,AND,or,OR)
     * $params['df']                 = (string) Field to use as default where no field prefix is given in the query string. This parameter can only be used when the `q` query string parameter is specified.
     * $params['expand_wildcards']   = (any)
     * $params['ignore_throttled']   = (boolean) If `true`, concrete, expanded or aliased indexes are ignored when frozen.
     * $params['ignore_unavailable'] = (boolean) If `false`, the request returns an error if it targets a missing or closed index.
     * $params['lenient']            = (boolean) If `true`, format-based query failures (such as providing text to a numeric field) in the query string will be ignored.
     * $params['min_score']          = (number) Sets the minimum `_score` value that documents must have to be included in the result.
     * $params['preference']         = (string) Specifies the node or shard the operation should be performed on. Random by default. (Default = random)
     * $params['q']                  = (string) Query in the Lucene query string syntax.
     * $params['routing']            = (any) A custom value used to route operations to a specific shard.
     * $params['terminate_after']    = (integer) Maximum number of documents to collect for each shard. If a query reaches this limit, OpenSearch terminates the query early. OpenSearch collects documents before sorting.
     * $params['pretty']             = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']              = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']        = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']             = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']        = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']               = (array) Query to restrict the results specified with the Query DSL (optional)
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function count(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(Count::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Creates point in time context.
     *
     * $params['index']                      = (array) A comma-separated list of indexes; use `_all` or empty string to perform the operation on all indexes. (Required)
     * $params['allow_partial_pit_creation'] = (boolean) Allow if point in time can be created with partial failures.
     * $params['expand_wildcards']           = (any) Whether to expand wildcard expression to concrete indexes that are open, closed or both.
     * $params['keep_alive']                 = (string) Specify the keep alive for point in time.
     * $params['preference']                 = (string) Specify the node or shard the operation should be performed on. (Default = random)
     * $params['routing']                    = (any) A comma-separated list of specific routing values.
     * $params['pretty']                     = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                      = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']                = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                     = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']                = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function createPit(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');

        $endpoint = $this->endpointFactory->getEndpoint(CreatePit::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);

        return $this->performRequest($endpoint);
    }

    /**
     * Removes a document from the index.
     *
     * $params['id']                     = (string) The unique identifier for the document. (Required)
     * $params['index']                  = (string) Name of the target index. (Required)
     * $params['if_primary_term']        = (integer) Only perform the operation if the document has this primary term.
     * $params['if_seq_no']              = (integer) Only perform the operation if the document has this sequence number.
     * $params['refresh']                = (any) If `true`, OpenSearch refreshes the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` do nothing with refreshes. Valid values: `true`, `false`, `wait_for`.
     * $params['routing']                = (any) A custom value used to route operations to a specific shard.
     * $params['timeout']                = (string) Period to wait for active shards.
     * $params['version']                = (integer) Explicit version number for concurrency control. The specified version must match the current version of the document for the request to succeed.
     * $params['version_type']           = (any) The specific version type: `external`, `external_gte`.
     * $params['wait_for_active_shards'] = (any) The number of shard copies that must be active before proceeding with the operation. Set to `all` or any positive integer up to the total number of shards in the index (`number_of_replicas+1`).
     * $params['pretty']                 = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                  = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']            = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                 = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']            = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function delete(array $params = [])
    {
        $id = $this->extractArgument($params, 'id');
        $index = $this->extractArgument($params, 'index');

        $endpoint = $this->endpointFactory->getEndpoint(Delete::class);
        $endpoint->setParams($params);
        $endpoint->setId($id);
        $endpoint->setIndex($index);

        return $this->performRequest($endpoint);
    }

    /**
     * Deletes all active point in time searches.
     *
     * $params['pretty']      = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']       = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace'] = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']      = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path'] = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function deleteAllPits(array $params = [])
    {
        $endpoint = $this->endpointFactory->getEndpoint(DeleteAllPits::class);
        $endpoint->setParams($params);

        return $this->performRequest($endpoint);
    }

    /**
     * Deletes documents matching the provided query.
     *
     * $params['index']                  = (array) A comma-separated list of data streams, indexes, and aliases to search. Supports wildcards (`*`). To search all data streams or indexes, omit this parameter or use `*` or `_all`. (Required)
     * $params['_source']                = (any) Set to `true` or `false` to return the `_source` field or not, or a list of fields to return.
     * $params['_source_excludes']       = (array) List of fields to exclude from the returned `_source` field.
     * $params['_source_includes']       = (array) List of fields to extract and return from the `_source` field.
     * $params['allow_no_indices']       = (boolean) If `false`, the request returns an error if any wildcard expression, index alias, or `_all` value targets only missing or closed indexes. This behavior applies even if the request targets other open indexes. For example, a request targeting `foo*,bar*` returns an error if an index starts with `foo` but no index starts with `bar`.
     * $params['analyze_wildcard']       = (boolean) If `true`, wildcard and prefix queries are analyzed. (Default = false)
     * $params['analyzer']               = (string) Analyzer to use for the query string.
     * $params['conflicts']              = (any) What to do if delete by query hits version conflicts: `abort` or `proceed`.
     * $params['default_operator']       = (enum) The default operator for query string query: `AND` or `OR`. (Options = and,AND,or,OR)
     * $params['df']                     = (string) Field to use as default where no field prefix is given in the query string.
     * $params['expand_wildcards']       = (any) Type of index that wildcard patterns can match. If the request can target data streams, this argument determines whether wildcard expressions match hidden data streams. Supports comma-separated values, such as `open,hidden`. Valid values are: `all`, `open`, `closed`, `hidden`, `none`.
     * $params['from']                   = (integer) Starting offset. (Default = 0)
     * $params['ignore_unavailable']     = (boolean) If `false`, the request returns an error if it targets a missing or closed index.
     * $params['lenient']                = (boolean) If `true`, format-based query failures (such as providing text to a numeric field) in the query string will be ignored.
     * $params['max_docs']               = (integer) Maximum number of documents to process. Defaults to all documents.
     * $params['preference']             = (string) Specifies the node or shard the operation should be performed on. Random by default. (Default = random)
     * $params['q']                      = (string) Query in the Lucene query string syntax.
     * $params['refresh']                = (any) If `true`, OpenSearch refreshes all shards involved in the delete by query after the request completes.
     * $params['request_cache']          = (boolean) If `true`, the request cache is used for this request. Defaults to the index-level setting.
     * $params['requests_per_second']    = (number) The throttle for this request in sub-requests per second. (Default = 0)
     * $params['routing']                = (any) A custom value used to route operations to a specific shard.
     * $params['scroll']                 = (string) Period to retain the search context for scrolling.
     * $params['scroll_size']            = (integer) Size of the scroll request that powers the operation. (Default = 100)
     * $params['search_timeout']         = (string) Explicit timeout for each search request. Defaults to no timeout.
     * $params['search_type']            = (any) The type of the search operation. Available options: `query_then_fetch`, `dfs_query_then_fetch`.
     * $params['size']                   = (integer) Deprecated, use `max_docs` instead.
     * $params['slices']                 = (any) The number of slices this task should be divided into.
     * $params['sort']                   = (array) A comma-separated list of <field>:<direction> pairs.
     * $params['stats']                  = (array) Specific `tag` of the request for logging and statistical purposes.
     * $params['terminate_after']        = (integer) Maximum number of documents to collect for each shard. If a query reaches this limit, OpenSearch terminates the query early. OpenSearch collects documents before sorting. Use with caution. OpenSearch applies this parameter to each shard handling the request. When possible, let OpenSearch perform early termination automatically. Avoid specifying this parameter for requests that target data streams with backing indexes across multiple data tiers.
     * $params['timeout']                = (string) Period each deletion request waits for active shards.
     * $params['version']                = (boolean) If `true`, returns the document version as part of a hit.
     * $params['wait_for_active_shards'] = (any) The number of shard copies that must be active before proceeding with the operation. Set to all or any positive integer up to the total number of shards in the index (`number_of_replicas+1`).
     * $params['wait_for_completion']    = (boolean) If `true`, the request blocks until the operation is complete. (Default = true)
     * $params['pretty']                 = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                  = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']            = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                 = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']            = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']                   = (array) The search definition using the Query DSL (Required)
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function deleteByQuery(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(DeleteByQuery::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Changes the number of requests per second for a particular Delete By Query operation.
     *
     * $params['task_id']             = (string) The ID for the task. (Required)
     * $params['requests_per_second'] = (number) The throttle for this request in sub-requests per second.
     * $params['pretty']              = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']               = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']         = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']              = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']         = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function deleteByQueryRethrottle(array $params = [])
    {
        $task_id = $this->extractArgument($params, 'task_id');

        $endpoint = $this->endpointFactory->getEndpoint(DeleteByQueryRethrottle::class);
        $endpoint->setParams($params);
        $endpoint->setTaskId($task_id);

        return $this->performRequest($endpoint);
    }

    /**
     * Deletes one or more point in time searches based on the IDs passed.
     *
     * $params['pretty']      = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']       = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace'] = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']      = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path'] = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']        = (array) The point-in-time ids to be deleted
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function deletePit(array $params = [])
    {
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(DeletePit::class);
        $endpoint->setParams($params);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Deletes a script.
     *
     * $params['id']                      = (string) Identifier for the stored script or search template. (Required)
     * $params['cluster_manager_timeout'] = (string) Operation timeout for connection to cluster-manager node.
     * $params['master_timeout']          = (string) Period to wait for a connection to the cluster-manager node. If no response is received before the timeout expires, the request fails and returns an error.
     * $params['timeout']                 = (string) Period to wait for a response. If no response is received before the timeout expires, the request fails and returns an error.
     * $params['pretty']                  = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                   = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']             = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                  = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']             = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function deleteScript(array $params = [])
    {
        $id = $this->extractArgument($params, 'id');

        $endpoint = $this->endpointFactory->getEndpoint(DeleteScript::class);
        $endpoint->setParams($params);
        $endpoint->setId($id);

        return $this->performRequest($endpoint);
    }

    /**
     * Returns information about whether a document exists in an index.
     *
     * $params['id']               = (string) Identifier of the document. (Required)
     * $params['index']            = (string) A comma-separated list of data streams, indexes, and aliases. Supports wildcards (`*`). (Required)
     * $params['_source']          = (any) `true` or `false` to return the `_source` field or not, or a list of fields to return.
     * $params['_source_excludes'] = (any) A comma-separated list of source fields to exclude in the response.
     * $params['_source_includes'] = (any) A comma-separated list of source fields to include in the response.
     * $params['preference']       = (string) Specifies the node or shard the operation should be performed on. Random by default. (Default = random)
     * $params['realtime']         = (boolean) If `true`, the request is real time as opposed to near real time.
     * $params['refresh']          = (any) If `true`, OpenSearch refreshes all shards involved in the delete by query after the request completes.
     * $params['routing']          = (any) Target the specified primary shard.
     * $params['stored_fields']    = (any) List of stored fields to return as part of a hit. If no fields are specified, no stored fields are included in the response. If this field is specified, the `_source` parameter defaults to false.
     * $params['version']          = (integer) Explicit version number for concurrency control. The specified version must match the current version of the document for the request to succeed.
     * $params['version_type']     = (any) The specific version type: `external`, `external_gte`.
     * $params['pretty']           = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']            = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']      = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']           = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']      = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return bool
     */
    public function exists(array $params = []): bool
    {
        $id = $this->extractArgument($params, 'id');
        $index = $this->extractArgument($params, 'index');

        // Legacy option to manually make this verbose so we can check status code.
        // @todo remove in 3.0.0
        $params['client']['verbose'] = true;

        $endpoint = $this->endpointFactory->getEndpoint(Exists::class);
        $endpoint->setParams($params);
        $endpoint->setId($id);
        $endpoint->setIndex($index);

        return BooleanRequestWrapper::sendRequest($endpoint, $this->httpTransport);
    }

    /**
     * Returns information about whether a document source exists in an index.
     *
     * $params['id']               = (string) Identifier of the document. (Required)
     * $params['index']            = (string) A comma-separated list of data streams, indexes, and aliases. Supports wildcards (`*`). (Required)
     * $params['_source']          = (any) `true` or `false` to return the `_source` field or not, or a list of fields to return.
     * $params['_source_excludes'] = (any) A comma-separated list of source fields to exclude in the response.
     * $params['_source_includes'] = (any) A comma-separated list of source fields to include in the response.
     * $params['preference']       = (string) Specifies the node or shard the operation should be performed on. Random by default. (Default = random)
     * $params['realtime']         = (boolean) If `true`, the request is real time as opposed to near real time.
     * $params['refresh']          = (any) If `true`, OpenSearch refreshes all shards involved in the delete by query after the request completes.
     * $params['routing']          = (any) Target the specified primary shard.
     * $params['version']          = (integer) Explicit version number for concurrency control. The specified version must match the current version of the document for the request to succeed.
     * $params['version_type']     = (any) The specific version type: `external`, `external_gte`.
     * $params['pretty']           = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']            = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']      = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']           = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']      = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return bool
     */
    public function existsSource(array $params = []): bool
    {
        $id = $this->extractArgument($params, 'id');
        $index = $this->extractArgument($params, 'index');

        // Legacy option to manually make this verbose so we can check status code.
        // @todo remove in 3.0.0
        $params['client']['verbose'] = true;

        $endpoint = $this->endpointFactory->getEndpoint(ExistsSource::class);
        $endpoint->setParams($params);
        $endpoint->setId($id);
        $endpoint->setIndex($index);

        return BooleanRequestWrapper::sendRequest($endpoint, $this->httpTransport);
    }

    /**
     * Returns information about why a specific document matches (or doesn't match) a query.
     *
     * $params['id']               = (string) Defines the document ID. (Required)
     * $params['index']            = (string) Index names used to limit the request. Only a single index name can be provided to this parameter. (Required)
     * $params['_source']          = (any) Set to `true` or `false` to return the `_source` field or not, or a list of fields to return.
     * $params['_source_excludes'] = (any) A comma-separated list of source fields to exclude from the response.
     * $params['_source_includes'] = (any) A comma-separated list of source fields to include in the response.
     * $params['analyze_wildcard'] = (boolean) If `true`, wildcard and prefix queries are analyzed. (Default = false)
     * $params['analyzer']         = (string) Analyzer to use for the query string. This parameter can only be used when the `q` query string parameter is specified.
     * $params['default_operator'] = (enum) The default operator for query string query: `AND` or `OR`. (Options = and,AND,or,OR)
     * $params['df']               = (string) Field to use as default where no field prefix is given in the query string. (Default = _all)
     * $params['lenient']          = (boolean) If `true`, format-based query failures (such as providing text to a numeric field) in the query string will be ignored.
     * $params['preference']       = (string) Specifies the node or shard the operation should be performed on. Random by default. (Default = random)
     * $params['q']                = (string) Query in the Lucene query string syntax.
     * $params['routing']          = (any) A custom value used to route operations to a specific shard.
     * $params['stored_fields']    = (any) A comma-separated list of stored fields to return in the response.
     * $params['pretty']           = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']            = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']      = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']           = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']      = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']             = (array) The query definition using the Query DSL
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function explain(array $params = [])
    {
        $id = $this->extractArgument($params, 'id');
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(Explain::class);
        $endpoint->setParams($params);
        $endpoint->setId($id);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Returns the information about the capabilities of fields among multiple indexes.
     *
     * $params['index']              = (array) A comma-separated list of data streams, indexes, and aliases used to limit the request. Supports wildcards (*). To target all data streams and indexes, omit this parameter or use * or `_all`.
     * $params['allow_no_indices']   = (boolean) If `false`, the request returns an error if any wildcard expression, index alias, or `_all` value targets only missing or closed indexes. This behavior applies even if the request targets other open indexes. For example, a request targeting `foo*,bar*` returns an error if an index starts with foo but no index starts with bar.
     * $params['expand_wildcards']   = (any) The type of index that wildcard patterns can match. If the request can target data streams, this argument determines whether wildcard expressions match hidden data streams. Supports comma-separated values, such as `open,hidden`.
     * $params['fields']             = (any) A comma-separated list of fields to retrieve capabilities for. Wildcard (`*`) expressions are supported.
     * $params['ignore_unavailable'] = (boolean) If `true`, missing or closed indexes are not included in the response.
     * $params['include_unmapped']   = (boolean) If `true`, unmapped fields are included in the response. (Default = false)
     * $params['pretty']             = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']              = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']        = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']             = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']        = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']               = (array) An index filter specified with the Query DSL
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function fieldCaps(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(FieldCaps::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Returns a document.
     *
     * $params['id']               = (string) The unique identifier of the document. (Required)
     * $params['index']            = (string) The name of the index containing the document. (Required)
     * $params['_source']          = (any) Set to `true` or `false` to return the `_source` field or not, or a list of fields to return.
     * $params['_source_excludes'] = (any) A comma-separated list of source fields to exclude in the response.
     * $params['_source_includes'] = (any) A comma-separated list of source fields to include in the response.
     * $params['preference']       = (string) Specifies the node or shard the operation should be performed on. Random by default. (Default = random)
     * $params['realtime']         = (boolean) If `true`, the request is real time as opposed to near real time.
     * $params['refresh']          = (any) If `true`, OpenSearch refreshes the affected shards to make this operation visible to search. If `false`, do nothing with refreshes.
     * $params['routing']          = (any) Target the specified primary shard.
     * $params['stored_fields']    = (any) List of stored fields to return as part of a hit. If no fields are specified, no stored fields are included in the response. If this field is specified, the `_source` parameter defaults to false.
     * $params['version']          = (integer) Explicit version number for concurrency control. The specified version must match the current version of the document for the request to succeed.
     * $params['version_type']     = (any) The specific version type: `internal`, `external`, `external_gte`.
     * $params['pretty']           = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']            = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']      = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']           = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']      = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function get(array $params = [])
    {
        $id = $this->extractArgument($params, 'id');
        $index = $this->extractArgument($params, 'index');

        $endpoint = $this->endpointFactory->getEndpoint(Get::class);
        $endpoint->setParams($params);
        $endpoint->setId($id);
        $endpoint->setIndex($index);

        return $this->performRequest($endpoint);
    }

    /**
     * Lists all active point in time searches.
     *
     * $params['pretty']      = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']       = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace'] = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']      = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path'] = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function getAllPits(array $params = [])
    {
        $endpoint = $this->endpointFactory->getEndpoint(GetAllPits::class);
        $endpoint->setParams($params);

        return $this->performRequest($endpoint);
    }

    /**
     * Returns a script.
     *
     * $params['id']                      = (string) Identifier for the stored script or search template. (Required)
     * $params['cluster_manager_timeout'] = (string) Operation timeout for connection to cluster-manager node.
     * $params['master_timeout']          = (string) Specify timeout for connection to master
     * $params['pretty']                  = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                   = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']             = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                  = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']             = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function getScript(array $params = [])
    {
        $id = $this->extractArgument($params, 'id');

        $endpoint = $this->endpointFactory->getEndpoint(GetScript::class);
        $endpoint->setParams($params);
        $endpoint->setId($id);

        return $this->performRequest($endpoint);
    }

    /**
     * Returns all script contexts.
     *
     * $params['pretty']      = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']       = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace'] = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']      = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path'] = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function getScriptContext(array $params = [])
    {
        $endpoint = $this->endpointFactory->getEndpoint(GetScriptContext::class);
        $endpoint->setParams($params);

        return $this->performRequest($endpoint);
    }

    /**
     * Returns available script types, languages and contexts.
     *
     * $params['pretty']      = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']       = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace'] = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']      = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path'] = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function getScriptLanguages(array $params = [])
    {
        $endpoint = $this->endpointFactory->getEndpoint(GetScriptLanguages::class);
        $endpoint->setParams($params);

        return $this->performRequest($endpoint);
    }

    /**
     * Returns the source of a document.
     *
     * $params['id']               = (string) The unique identifier of the document. (Required)
     * $params['index']            = (string) The name of the index containing the document. (Required)
     * $params['_source']          = (any) Set to `true` or `false` to return the `_source` field or not, or a list of fields to return.
     * $params['_source_excludes'] = (any) A comma-separated list of source fields to exclude in the response.
     * $params['_source_includes'] = (any) A comma-separated list of source fields to include in the response.
     * $params['preference']       = (string) Specifies the node or shard the operation should be performed on. Random by default. (Default = random)
     * $params['realtime']         = (boolean) Boolean) If `true`, the request is real time as opposed to near real time.
     * $params['refresh']          = (any) If `true`, OpenSearch refreshes the affected shards to make this operation visible to search. If `false`, do nothing with refreshes.
     * $params['routing']          = (any) Target the specified primary shard.
     * $params['version']          = (integer) Explicit version number for concurrency control. The specified version must match the current version of the document for the request to succeed.
     * $params['version_type']     = (any) The specific version type. One of `internal`, `external`, `external_gte`.
     * $params['pretty']           = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']            = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']      = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']           = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']      = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function getSource(array $params = [])
    {
        $id = $this->extractArgument($params, 'id');
        $index = $this->extractArgument($params, 'index');

        $endpoint = $this->endpointFactory->getEndpoint(GetSource::class);
        $endpoint->setParams($params);
        $endpoint->setId($id);
        $endpoint->setIndex($index);

        return $this->performRequest($endpoint);
    }

    /**
     * Creates or updates a document in an index.
     *
     * $params['index']                  = (string) Name of the data stream or index to target. (Required)
     * $params['id']                     = (string) The unique identifier for the document.
     * $params['if_primary_term']        = (integer) Only perform the operation if the document has this primary term.
     * $params['if_seq_no']              = (integer) Only perform the operation if the document has this sequence number.
     * $params['op_type']                = (any) Set to create to only index the document if it does not already exist (put if absent). If a document with the specified `_id` already exists, the indexing operation will fail. Same as using the `<index>/_create` endpoint. Valid values: `index`, `create`. If document id is specified, it defaults to `index`. Otherwise, it defaults to `create`.
     * $params['pipeline']               = (string) ID of the pipeline to use to preprocess incoming documents. If the index has a default ingest pipeline specified, then setting the value to `_none` disables the default ingest pipeline for this request. If a final pipeline is configured it will always run, regardless of the value of this parameter.
     * $params['refresh']                = (any) If `true`, OpenSearch refreshes the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` do nothing with refreshes. Valid values: `true`, `false`, `wait_for`.
     * $params['require_alias']          = (boolean) If `true`, the destination must be an index alias. (Default = false)
     * $params['routing']                = (any) A custom value used to route operations to a specific shard.
     * $params['timeout']                = (string) Period the request waits for the following operations: automatic index creation, dynamic mapping updates, waiting for active shards.
     * $params['version']                = (integer) Explicit version number for concurrency control. The specified version must match the current version of the document for the request to succeed.
     * $params['version_type']           = (any) The specific version type: `external`, `external_gte`.
     * $params['wait_for_active_shards'] = (any) The number of shard copies that must be active before proceeding with the operation. Set to all or any positive integer up to the total number of shards in the index (`number_of_replicas+1`).
     * $params['pretty']                 = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                  = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']            = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                 = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']            = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']                   = (array) The document (Required)
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function index(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');
        $id = $this->extractArgument($params, 'id');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(Index::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);
        $endpoint->setId($id);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Returns basic information about the cluster.
     *
     * $params['pretty']      = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']       = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace'] = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']      = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path'] = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function info(array $params = [])
    {
        $endpoint = $this->endpointFactory->getEndpoint(Info::class);
        $endpoint->setParams($params);

        return $this->performRequest($endpoint);
    }

    /**
     * Allows to get multiple documents in one request.
     *
     * $params['index']            = (string) The name of the index to retrieve documents from when `ids` are specified, or when a document in the `docs` array does not specify an index.
     * $params['_source']          = (any) Set to `true` or `false` to return the `_source` field or not, or a list of fields to return.
     * $params['_source_excludes'] = (any) A comma-separated list of source fields to exclude from the response. You can also use this parameter to exclude fields from the subset specified in `_source_includes` query parameter.
     * $params['_source_includes'] = (any) A comma-separated list of source fields to include in the response. If this parameter is specified, only these source fields are returned. You can exclude fields from this subset using the `_source_excludes` query parameter. If the `_source` parameter is `false`, this parameter is ignored.
     * $params['preference']       = (string) Specifies the node or shard the operation should be performed on. Random by default. (Default = random)
     * $params['realtime']         = (boolean) If `true`, the request is real time as opposed to near real time.
     * $params['refresh']          = (any) If `true`, the request refreshes relevant shards before retrieving documents.
     * $params['routing']          = (any) A custom value used to route operations to a specific shard.
     * $params['stored_fields']    = (any) If `true`, retrieves the document fields stored in the index rather than the document `_source`.
     * $params['pretty']           = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']            = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']      = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']           = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']      = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']             = (array) Document identifiers; can be either `docs` (containing full document information) or `ids` (when index is provided in the URL. (Required)
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function mget(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(Mget::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Allows to execute several search operations in one request.
     *
     * $params['index']                         = (array) A comma-separated list of data streams, indexes, and index aliases to search.
     * $params['ccs_minimize_roundtrips']       = (boolean) If `true`, network round-trips between the coordinating node and remote clusters are minimized for cross-cluster search requests. (Default = true)
     * $params['max_concurrent_searches']       = (integer) Maximum number of concurrent searches the multi search API can execute.
     * $params['max_concurrent_shard_requests'] = (integer) Maximum number of concurrent shard requests that each sub-search request executes per node. (Default = 5)
     * $params['pre_filter_shard_size']         = (integer) Defines a threshold that enforces a pre-filter roundtrip to prefilter search shards based on query rewriting if the number of shards the search request expands to exceeds the threshold. This filter roundtrip can limit the number of shards significantly if for instance a shard can not match any documents based on its rewrite method i.e., if date filters are mandatory to match but the shard bounds and the query are disjoint.
     * $params['rest_total_hits_as_int']        = (boolean) If `true`, `hits.total` are returned as an integer in the response. Defaults to false, which returns an object. (Default = false)
     * $params['search_type']                   = (any) Indicates whether global term and document frequencies should be used when scoring returned documents.
     * $params['typed_keys']                    = (boolean) Specifies whether aggregation and suggester names should be prefixed by their respective types in the response.
     * $params['pretty']                        = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                         = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']                   = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                        = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']                   = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']                          = (array) The request definitions (metadata-search request definition pairs), separated by newlines (Required)
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function msearch(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(Msearch::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Allows to execute several search template operations in one request.
     *
     * $params['index']                   = (array) A comma-separated list of data streams, indexes, and aliases to search. Supports wildcards (`*`). To search all data streams and indexes, omit this parameter or use `*`.
     * $params['ccs_minimize_roundtrips'] = (boolean) If `true`, network round-trips are minimized for cross-cluster search requests. (Default = true)
     * $params['max_concurrent_searches'] = (integer) Maximum number of concurrent searches the API can run.
     * $params['rest_total_hits_as_int']  = (boolean) If `true`, the response returns `hits.total` as an integer. If `false`, it returns `hits.total` as an object. (Default = false)
     * $params['search_type']             = (any) The type of the search operation. Available options: `query_then_fetch`, `dfs_query_then_fetch`.
     * $params['typed_keys']              = (boolean) If `true`, the response prefixes aggregation and suggester names with their respective types.
     * $params['pretty']                  = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                   = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']             = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                  = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']             = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']                    = (array) The request definitions (metadata-search request definition pairs), separated by newlines (Required)
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function msearchTemplate(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(MsearchTemplate::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Returns multiple termvectors in one request.
     *
     * $params['index']            = (string) The name of the index that contains the document.
     * $params['field_statistics'] = (boolean) If `true`, the response includes the document count, sum of document frequencies, and sum of total term frequencies. (Default = true)
     * $params['fields']           = (any)
     * $params['ids']              = (array) A comma-separated list of documents IDs. You must provide either the `docs` field in the request body or specify `ids` as a query parameter or in the request body.
     * $params['offsets']          = (boolean) If `true`, the response includes term offsets. (Default = true)
     * $params['payloads']         = (boolean) If `true`, the response includes term payloads. (Default = true)
     * $params['positions']        = (boolean) If `true`, the response includes term positions. (Default = true)
     * $params['preference']       = (string) Specifies the node or shard on which the operation should be performed. See [preference query parameter]({{site.url}}{{site.baseurl}}/api-reference/search-apis/search/#the-preference-query-parameter) for a list of available options. By default the requests are routed randomly to available shard copies (primary or replica), with no guarantee of consistency across repeated queries.
     * $params['realtime']         = (boolean) If `true`, the request is real time as opposed to near real time. (Default = true)
     * $params['routing']          = (any) A custom value used to route operations to a specific shard.
     * $params['term_statistics']  = (boolean) If `true`, the response includes term frequency and document frequency. (Default = false)
     * $params['version']          = (integer) If `true`, returns the document version as part of a hit.
     * $params['version_type']     = (any) The specific version type.
     * $params['pretty']           = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']            = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']      = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']           = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']      = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']             = (array) Define ids, documents, parameters or a list of parameters per document here. You must at least provide a list of document ids. See documentation.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function mtermvectors(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(MTermVectors::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Returns whether the cluster is running.
     *
     * $params['pretty']      = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']       = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace'] = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']      = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path'] = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return bool
     */
    public function ping(array $params = []): bool
    {
        // Legacy option to manually make this verbose so we can check status code.
        // @todo remove in 3.0.0
        $params['client']['verbose'] = true;

        $endpoint = $this->endpointFactory->getEndpoint(Ping::class);
        $endpoint->setParams($params);

        return BooleanRequestWrapper::sendRequest($endpoint, $this->httpTransport);
    }

    /**
     * Creates or updates a script.
     *
     * $params['id']                      = (string) Identifier for the stored script or search template. Must be unique within the cluster. (Required)
     * $params['context']                 = (string) Context in which the script or search template should run. To prevent errors, the API immediately compiles the script or template in this context.
     * $params['cluster_manager_timeout'] = (string) Operation timeout for connection to cluster-manager node.
     * $params['master_timeout']          = (string) Period to wait for a connection to the cluster-manager node. If no response is received before the timeout expires, the request fails and returns an error.
     * $params['timeout']                 = (string) Period to wait for a response. If no response is received before the timeout expires, the request fails and returns an error.
     * $params['pretty']                  = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                   = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']             = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                  = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']             = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']                    = (array) The document (Required)
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function putScript(array $params = [])
    {
        $id = $this->extractArgument($params, 'id');
        $context = $this->extractArgument($params, 'context');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(PutScript::class);
        $endpoint->setParams($params);
        $endpoint->setId($id);
        $endpoint->setContext($context);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Allows to evaluate the quality of ranked search results over a set of typical search queries.
     *
     * $params['index']              = (array) A comma-separated list of data streams, indexes, and index aliases used to limit the request. Wildcard (`*`) expressions are supported. To target all data streams and indexes in a cluster, omit this parameter or use `_all` or `*`.
     * $params['allow_no_indices']   = (boolean) If `false`, the request returns an error if any wildcard expression, index alias, or `_all` value targets only missing or closed indexes. This behavior applies even if the request targets other open indexes. For example, a request targeting `foo*,bar*` returns an error if an index starts with `foo` but no index starts with `bar`.
     * $params['expand_wildcards']   = (any) Whether to expand wildcard expression to concrete indexes that are open, closed or both.
     * $params['ignore_unavailable'] = (boolean) If `true`, missing or closed indexes are not included in the response.
     * $params['search_type']        = (any) Search operation type
     * $params['pretty']             = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']              = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']        = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']             = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']        = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']               = (array) The ranking evaluation search definition, including search requests, document ratings and ranking metric definition. (Required)
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function rankEval(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(RankEval::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Allows to copy documents from one index to another, optionally filtering the sourcedocuments by a query, changing the destination index settings, or fetching thedocuments from a remote cluster.
     *
     * $params['max_docs']               = (integer) Maximum number of documents to process. By default, all documents.
     * $params['refresh']                = (any) If `true`, the request refreshes affected shards to make this operation visible to search.
     * $params['requests_per_second']    = (number) The throttle for this request in sub-requests per second. Defaults to no throttle. (Default = 0)
     * $params['require_alias']          = (boolean)
     * $params['scroll']                 = (string) Specifies how long a consistent view of the index should be maintained for scrolled search.
     * $params['slices']                 = (any) The number of slices this task should be divided into. Defaults to 1 slice, meaning the task isn't sliced into subtasks.
     * $params['timeout']                = (string) Period each indexing waits for automatic index creation, dynamic mapping updates, and waiting for active shards.
     * $params['wait_for_active_shards'] = (any) The number of shard copies that must be active before proceeding with the operation. Set to `all` or any positive integer up to the total number of shards in the index (`number_of_replicas+1`).
     * $params['wait_for_completion']    = (boolean) If `true`, the request blocks until the operation is complete. (Default = true)
     * $params['pretty']                 = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                  = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']            = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                 = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']            = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']                   = (array) The search definition using the Query DSL and the prototype for the index request. (Required)
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function reindex(array $params = [])
    {
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(Reindex::class);
        $endpoint->setParams($params);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Changes the number of requests per second for a particular reindex operation.
     *
     * $params['task_id']             = (string) Identifier for the task. (Required)
     * $params['requests_per_second'] = (number) The throttle for this request in sub-requests per second.
     * $params['pretty']              = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']               = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']         = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']              = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']         = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function reindexRethrottle(array $params = [])
    {
        $task_id = $this->extractArgument($params, 'task_id');

        $endpoint = $this->endpointFactory->getEndpoint(ReindexRethrottle::class);
        $endpoint->setParams($params);
        $endpoint->setTaskId($task_id);

        return $this->performRequest($endpoint);
    }

    /**
     * Allows to use the Mustache language to pre-render a search definition.
     *
     * $params['id']          = (string) ID of the search template to render. If no `source` is specified, this or the `id` request body parameter is required.
     * $params['pretty']      = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']       = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace'] = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']      = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path'] = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']        = (array) The search definition template and its parameters.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function renderSearchTemplate(array $params = [])
    {
        $id = $this->extractArgument($params, 'id');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(RenderSearchTemplate::class);
        $endpoint->setParams($params);
        $endpoint->setId($id);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Allows an arbitrary script to be executed and a result to be returned.
     *
     * $params['pretty']      = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']       = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace'] = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']      = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path'] = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']        = (array) The script to execute
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function scriptsPainlessExecute(array $params = [])
    {
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(ScriptsPainlessExecute::class);
        $endpoint->setParams($params);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Allows to retrieve a large numbers of results from a single search request.
     *
     * $params['scroll_id']              = DEPRECATED (string) The scroll ID
     * $params['rest_total_hits_as_int'] = (boolean) If `true`, the API response's `hit.total` property is returned as an integer. If `false`, the API response's `hit.total` property is returned as an object. (Default = false)
     * $params['scroll']                 = (string) Period to retain the search context for scrolling.
     * $params['pretty']                 = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                  = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']            = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                 = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']            = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function scroll(array $params = [])
    {
        $scroll_id = $this->extractArgument($params, 'scroll_id');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(Scroll::class);
        $endpoint->setParams($params);
        $endpoint->setScrollId($scroll_id);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Returns results matching a query.
     *
     * $params['index']                         = (array) A comma-separated list of data streams, indexes, and aliases to search. Supports wildcards (`*`). To search all data streams and indexes, omit this parameter or use `*` or `_all`.
     * $params['_source']                       = (any) Indicates which source fields are returned for matching documents. These fields are returned in the `hits._source` property of the search response. Valid values are: `true` to return the entire document source; `false` to not return the document source; `<string>` to return the source fields that are specified as a comma-separated list (supports wildcard (`*`) patterns).
     * $params['_source_excludes']              = (any) A comma-separated list of source fields to exclude from the response. You can also use this parameter to exclude fields from the subset specified in `_source_includes` query parameter. If the `_source` parameter is `false`, this parameter is ignored.
     * $params['_source_includes']              = (any) A comma-separated list of source fields to include in the response. If this parameter is specified, only these source fields are returned. You can exclude fields from this subset using the `_source_excludes` query parameter. If the `_source` parameter is `false`, this parameter is ignored.
     * $params['allow_no_indices']              = (boolean) If `false`, the request returns an error if any wildcard expression, index alias, or `_all` value targets only missing or closed indexes. This behavior applies even if the request targets other open indexes. For example, a request targeting `foo*,bar*` returns an error if an index starts with `foo` but no index starts with `bar`.
     * $params['allow_partial_search_results']  = (boolean) If `true`, returns partial results if there are shard request timeouts or shard failures. If `false`, returns an error with no partial results. (Default = true)
     * $params['analyze_wildcard']              = (boolean) If `true`, wildcard and prefix queries are analyzed. This parameter can only be used when the q query string parameter is specified. (Default = false)
     * $params['analyzer']                      = (string) Analyzer to use for the query string. This parameter can only be used when the q query string parameter is specified.
     * $params['batched_reduce_size']           = (integer) The number of shard results that should be reduced at once on the coordinating node. This value should be used as a protection mechanism to reduce the memory overhead per search request if the potential number of shards in the request can be large. (Default = 512)
     * $params['cancel_after_time_interval']    = (string) The time after which the search request will be canceled. Request-level parameter takes precedence over `cancel_after_time_interval` cluster setting.
     * $params['ccs_minimize_roundtrips']       = (boolean) If `true`, network round-trips between the coordinating node and the remote clusters are minimized when executing cross-cluster search (CCS) requests. (Default = true)
     * $params['default_operator']              = (enum) The default operator for query string query: AND or OR. This parameter can only be used when the `q` query string parameter is specified. (Options = and,AND,or,OR)
     * $params['df']                            = (string) Field to use as default where no field prefix is given in the query string. This parameter can only be used when the q query string parameter is specified.
     * $params['docvalue_fields']               = (any) A comma-separated list of fields to return as the docvalue representation for each hit.
     * $params['expand_wildcards']              = (any) Type of index that wildcard patterns can match. If the request can target data streams, this argument determines whether wildcard expressions match hidden data streams. Supports comma-separated values, such as `open,hidden`.
     * $params['explain']                       = (boolean) If `true`, returns detailed information about score computation as part of a hit.
     * $params['from']                          = (integer) Starting document offset. Needs to be non-negative. By default, you cannot page through more than 10,000 hits using the `from` and `size` parameters. To page through more hits, use the `search_after` parameter. (Default = 0)
     * $params['ignore_throttled']              = (boolean) If `true`, concrete, expanded or aliased indexes will be ignored when frozen.
     * $params['ignore_unavailable']            = (boolean) If `false`, the request returns an error if it targets a missing or closed index.
     * $params['include_named_queries_score']   = (boolean) Indicates whether `hit.matched_queries` should be rendered as a map that includes the name of the matched query associated with its score (true) or as an array containing the name of the matched queries (false) (Default = false)
     * $params['lenient']                       = (boolean) If `true`, format-based query failures (such as providing text to a numeric field) in the query string will be ignored. This parameter can only be used when the `q` query string parameter is specified.
     * $params['max_concurrent_shard_requests'] = (integer) Defines the number of concurrent shard requests per node this search executes concurrently. This value should be used to limit the impact of the search on the cluster in order to limit the number of concurrent shard requests. (Default = 5)
     * $params['phase_took']                    = (boolean) Indicates whether to return phase-level `took` time values in the response. (Default = false)
     * $params['pre_filter_shard_size']         = (integer) Defines a threshold that enforces a pre-filter roundtrip to prefilter search shards based on query rewriting if the number of shards the search request expands to exceeds the threshold. This filter roundtrip can limit the number of shards significantly if for instance a shard can not match any documents based on its rewrite method (if date filters are mandatory to match but the shard bounds and the query are disjoint). When unspecified, the pre-filter phase is executed if any of these conditions is met: the request targets more than 128 shards; the request targets one or more read-only index; the primary sort of the query targets an indexed field.
     * $params['preference']                    = (string) Nodes and shards used for the search. By default, OpenSearch selects from eligible nodes and shards using adaptive replica selection, accounting for allocation awareness. Valid values are: `_only_local` to run the search only on shards on the local node; `_local` to, if possible, run the search on shards on the local node, or if not, select shards using the default method; `_only_nodes:<node-id>,<node-id>` to run the search on only the specified nodes IDs, where, if suitable shards exist on more than one selected node, use shards on those nodes using the default method, or if none of the specified nodes are available, select shards from any available node using the default method; `_prefer_nodes:<node-id>,<node-id>` to if possible, run the search on the specified nodes IDs, or if not, select shards using the default method; `_shards:<shard>,<shard>` to run the search only on the specified shards; `<custom-string>` (any string that does not start with `_`) to route searches with the same `<custom-string>` to the same shards in the same order. (Default = random)
     * $params['q']                             = (string) Query in the Lucene query string syntax using query parameter search. Query parameter searches do not support the full OpenSearch Query DSL but are handy for testing.
     * $params['request_cache']                 = (boolean) If `true`, the caching of search results is enabled for requests where `size` is `0`. Defaults to index level settings.
     * $params['rest_total_hits_as_int']        = (boolean) Indicates whether `hits.total` should be rendered as an integer or an object in the rest search response. (Default = false)
     * $params['routing']                       = (any) A custom value used to route operations to a specific shard.
     * $params['scroll']                        = (string) Period to retain the search context for scrolling. See Scroll search results. By default, this value cannot exceed `1d` (24 hours). You can change this limit using the `search.max_keep_alive` cluster-level setting.
     * $params['search_pipeline']               = (string) Customizable sequence of processing stages applied to search queries.
     * $params['search_type']                   = (any) How distributed term frequencies are calculated for relevance scoring.
     * $params['seq_no_primary_term']           = (boolean) If `true`, returns sequence number and primary term of the last modification of each hit.
     * $params['size']                          = (integer) Defines the number of hits to return. By default, you cannot page through more than 10,000 hits using the `from` and `size` parameters. To page through more hits, use the `search_after` parameter. (Default = 10)
     * $params['sort']                          = (any) A comma-separated list of <field>:<direction> pairs.
     * $params['stats']                         = (array) Specific `tag` of the request for logging and statistical purposes.
     * $params['stored_fields']                 = (any) A comma-separated list of stored fields to return as part of a hit. If no fields are specified, no stored fields are included in the response. If this field is specified, the `_source` parameter defaults to `false`. You can pass `_source: true` to return both source fields and stored fields in the search response.
     * $params['suggest_field']                 = (string) Specifies which field to use for suggestions.
     * $params['suggest_mode']                  = (enum) Specifies the suggest mode. This parameter can only be used when the `suggest_field` and `suggest_text` query string parameters are specified. (Options = always,missing,popular)
     * $params['suggest_size']                  = (integer) Number of suggestions to return. This parameter can only be used when the `suggest_field` and `suggest_text` query string parameters are specified.
     * $params['suggest_text']                  = (string) The source text for which the suggestions should be returned. This parameter can only be used when the `suggest_field` and `suggest_text` query string parameters are specified.
     * $params['terminate_after']               = (integer) Maximum number of documents to collect for each shard. If a query reaches this limit, OpenSearch terminates the query early. OpenSearch collects documents before sorting. Use with caution. OpenSearch applies this parameter to each shard handling the request. When possible, let OpenSearch perform early termination automatically. Avoid specifying this parameter for requests that target data streams with backing indexes across multiple data tiers. If set to `0` (default), the query does not terminate early.
     * $params['timeout']                       = (string) Specifies the period of time to wait for a response from each shard. If no response is received before the timeout expires, the request fails and returns an error.
     * $params['track_scores']                  = (boolean) If `true`, calculate and return document scores, even if the scores are not used for sorting.
     * $params['track_total_hits']              = (any) Number of hits matching the query to count accurately. If `true`, the exact number of hits is returned at the cost of some performance. If `false`, the response does not include the total number of hits matching the query.
     * $params['typed_keys']                    = (boolean) If `true`, aggregation and suggester names are be prefixed by their respective types in the response.
     * $params['verbose_pipeline']              = (boolean) Enables or disables verbose mode for the search pipeline. When verbose mode is enabled, detailed information about each processor in the search pipeline is included in the search response. This includes the processor name, execution status, input, output, and time taken for processing. This parameter is primarily intended for debugging purposes, allowing users to track how data flows and transforms through the search pipeline.
     * $params['version']                       = (boolean) If `true`, returns document version as part of a hit.
     * $params['pretty']                        = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                         = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']                   = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                        = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']                   = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']                          = (array) The search definition using the Query DSL
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function search(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(Search::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Returns information about the indexes and shards that a search request would be executed against.
     *
     * $params['index']              = (array) Returns the indexes and shards that a search request would be executed against.
     * $params['allow_no_indices']   = (boolean) If `false`, the request returns an error if any wildcard expression, index alias, or `_all` value targets only missing or closed indexes. This behavior applies even if the request targets other open indexes. For example, a request targeting `foo*,bar*` returns an error if an index starts with `foo` but no index starts with `bar`.
     * $params['expand_wildcards']   = (any) Type of index that wildcard patterns can match. If the request can target data streams, this argument determines whether wildcard expressions match hidden data streams. Supports comma-separated values, such as `open,hidden`. Valid values are: `all`, `open`, `closed`, `hidden`, `none`.
     * $params['ignore_unavailable'] = (boolean) If `false`, the request returns an error if it targets a missing or closed index.
     * $params['local']              = (boolean) If `true`, the request retrieves information from the local node only. (Default = false)
     * $params['preference']         = (string) Specifies the node or shard the operation should be performed on. Random by default. (Default = random)
     * $params['routing']            = (any) A custom value used to route operations to a specific shard.
     * $params['pretty']             = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']              = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']        = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']             = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']        = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function searchShards(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(SearchShards::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Allows to use the Mustache language to pre-render a search definition.
     *
     * $params['index']                   = (array) A comma-separated list of data streams, indexes, and aliases to search. Supports wildcards (*).
     * $params['allow_no_indices']        = (boolean) If `false`, the request returns an error if any wildcard expression, index alias, or `_all` value targets only missing or closed indexes. This behavior applies even if the request targets other open indexes. For example, a request targeting `foo*,bar*` returns an error if an index starts with `foo` but no index starts with `bar`.
     * $params['ccs_minimize_roundtrips'] = (boolean) If `true`, network round-trips are minimized for cross-cluster search requests. (Default = true)
     * $params['expand_wildcards']        = (any) Type of index that wildcard patterns can match. If the request can target data streams, this argument determines whether wildcard expressions match hidden data streams. Supports comma-separated values, such as `open,hidden`. Valid values are: `all`, `open`, `closed`, `hidden`, `none`.
     * $params['explain']                 = (boolean) If `true`, the response includes additional details about score computation as part of a hit.
     * $params['ignore_throttled']        = (boolean) If `true`, specified concrete, expanded, or aliased indexes are not included in the response when throttled.
     * $params['ignore_unavailable']      = (boolean) If `false`, the request returns an error if it targets a missing or closed index.
     * $params['phase_took']              = (boolean) Indicates whether to return phase-level `took` time values in the response. (Default = false)
     * $params['preference']              = (string) Specifies the node or shard the operation should be performed on. Random by default. (Default = random)
     * $params['profile']                 = (boolean) If `true`, the query execution is profiled.
     * $params['rest_total_hits_as_int']  = (boolean) If `true`, `hits.total` are rendered as an integer in the response. (Default = false)
     * $params['routing']                 = (any) A custom value used to route operations to a specific shard.
     * $params['scroll']                  = (string) Specifies how long a consistent view of the index should be maintained for scrolled search.
     * $params['search_pipeline']         = (string) Customizable sequence of processing stages applied to search queries.
     * $params['search_type']             = (any) The type of the search operation.
     * $params['typed_keys']              = (boolean) If `true`, the response prefixes aggregation and suggester names with their respective types.
     * $params['pretty']                  = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                   = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']             = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                  = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']             = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']                    = (array) The search definition template and its parameters. (Required)
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function searchTemplate(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(SearchTemplate::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Returns information and statistics about terms in the fields of a particular document.
     *
     * $params['index']            = (string) The name of the index containing the document. (Required)
     * $params['id']               = (string) The unique identifier of the document.
     * $params['field_statistics'] = (boolean) If `true`, the response includes the document count, sum of document frequencies, and sum of total term frequencies. (Default = true)
     * $params['fields']           = (any)
     * $params['offsets']          = (boolean) If `true`, the response includes term offsets. (Default = true)
     * $params['payloads']         = (boolean) If `true`, the response includes term payloads. (Default = true)
     * $params['positions']        = (boolean) If `true`, the response includes term positions. (Default = true)
     * $params['preference']       = (string) Specifies the node or shard on which the operation should be performed. See [preference query parameter]({{site.url}}{{site.baseurl}}/api-reference/search-apis/search/#the-preference-query-parameter) for a list of available options. By default the requests are routed randomly to available shard copies (primary or replica), with no guarantee of consistency across repeated queries.
     * $params['realtime']         = (boolean) If `true`, the request is real time as opposed to near real time. (Default = true)
     * $params['routing']          = (any) A custom value used to route operations to a specific shard.
     * $params['term_statistics']  = (boolean) If `true`, the response includes term frequency and document frequency. (Default = false)
     * $params['version']          = (integer) If `true`, returns the document version as part of a hit.
     * $params['version_type']     = (any) The specific version type.
     * $params['pretty']           = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']            = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']      = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']           = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']      = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']             = (array) Define parameters and or supply a document to get termvectors for. See documentation.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function termvectors(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');
        $id = $this->extractArgument($params, 'id');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(TermVectors::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);
        $endpoint->setId($id);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Updates a document with a script or partial document.
     *
     * $params['id']                     = (string) Document ID (Required)
     * $params['index']                  = (string) The name of the index (Required)
     * $params['_source']                = (any) Set to `false` to disable source retrieval. You can also specify a comma-separated list of the fields you want to retrieve.
     * $params['_source_excludes']       = (any) Specify the source fields you want to exclude.
     * $params['_source_includes']       = (any) Specify the source fields you want to retrieve.
     * $params['if_primary_term']        = (integer) Only perform the operation if the document has this primary term.
     * $params['if_seq_no']              = (integer) Only perform the operation if the document has this sequence number.
     * $params['lang']                   = (string) The script language. (Default = painless)
     * $params['refresh']                = (any) If 'true', OpenSearch refreshes the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` do nothing with refreshes.
     * $params['require_alias']          = (boolean) If `true`, the destination must be an index alias. (Default = false)
     * $params['retry_on_conflict']      = (integer) Specify how many times should the operation be retried when a conflict occurs. (Default = 0)
     * $params['routing']                = (any) A custom value used to route operations to a specific shard.
     * $params['timeout']                = (string) Period to wait for dynamic mapping updates and active shards. This guarantees OpenSearch waits for at least the timeout before failing. The actual wait time could be longer, particularly when multiple waits occur.
     * $params['wait_for_active_shards'] = (any) The number of shard copies that must be active before proceeding with the operations. Set to 'all' or any positive integer up to the total number of shards in the index (number_of_replicas+1). Defaults to 1 meaning the primary shard.
     * $params['pretty']                 = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                  = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']            = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                 = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']            = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']                   = (array) The request definition requires either `script` or partial `doc` (Required)
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function update(array $params = [])
    {
        $id = $this->extractArgument($params, 'id');
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(Update::class);
        $endpoint->setParams($params);
        $endpoint->setId($id);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Performs an update on every document in the index without changing the source,for example to pick up a mapping change.
     *
     * $params['index']                  = (array) A comma-separated list of data streams, indexes, and aliases to search. Supports wildcards (`*`). To search all data streams or indexes, omit this parameter or use `*` or `_all`. (Required)
     * $params['_source']                = (any) Set to `true` or `false` to return the `_source` field or not, or a list of fields to return.
     * $params['_source_excludes']       = (array) List of fields to exclude from the returned `_source` field.
     * $params['_source_includes']       = (array) List of fields to extract and return from the `_source` field.
     * $params['allow_no_indices']       = (boolean) If `false`, the request returns an error if any wildcard expression, index alias, or `_all` value targets only missing or closed indexes. This behavior applies even if the request targets other open indexes. For example, a request targeting `foo*,bar*` returns an error if an index starts with `foo` but no index starts with `bar`.
     * $params['analyze_wildcard']       = (boolean) If `true`, wildcard and prefix queries are analyzed. (Default = false)
     * $params['analyzer']               = (string) Analyzer to use for the query string.
     * $params['conflicts']              = (any) What to do if update by query hits version conflicts: `abort` or `proceed`.
     * $params['default_operator']       = (enum) The default operator for query string query: `AND` or `OR`. (Options = and,AND,or,OR)
     * $params['df']                     = (string) Field to use as default where no field prefix is given in the query string.
     * $params['expand_wildcards']       = (any) Type of index that wildcard patterns can match. If the request can target data streams, this argument determines whether wildcard expressions match hidden data streams. Supports comma-separated values, such as `open,hidden`. Valid values are: `all`, `open`, `closed`, `hidden`, `none`.
     * $params['from']                   = (integer) Starting offset. (Default = 0)
     * $params['ignore_unavailable']     = (boolean) If `false`, the request returns an error if it targets a missing or closed index.
     * $params['lenient']                = (boolean) If `true`, format-based query failures (such as providing text to a numeric field) in the query string will be ignored.
     * $params['max_docs']               = (integer) Maximum number of documents to process. Defaults to all documents.
     * $params['pipeline']               = (string) ID of the pipeline to use to preprocess incoming documents. If the index has a default ingest pipeline specified, then setting the value to `_none` disables the default ingest pipeline for this request. If a final pipeline is configured it will always run, regardless of the value of this parameter.
     * $params['preference']             = (string) Specifies the node or shard the operation should be performed on. Random by default. (Default = random)
     * $params['q']                      = (string) Query in the Lucene query string syntax.
     * $params['refresh']                = (any) If `true`, OpenSearch refreshes affected shards to make the operation visible to search.
     * $params['request_cache']          = (boolean) If `true`, the request cache is used for this request.
     * $params['requests_per_second']    = (number) The throttle for this request in sub-requests per second. (Default = 0)
     * $params['routing']                = (any) A custom value used to route operations to a specific shard.
     * $params['scroll']                 = (string) Period to retain the search context for scrolling.
     * $params['scroll_size']            = (integer) Size of the scroll request that powers the operation. (Default = 100)
     * $params['search_timeout']         = (string) Explicit timeout for each search request.
     * $params['search_type']            = (any) The type of the search operation. Available options: `query_then_fetch`, `dfs_query_then_fetch`.
     * $params['size']                   = (integer) Deprecated, use `max_docs` instead.
     * $params['slices']                 = (any) The number of slices this task should be divided into.
     * $params['sort']                   = (array) A comma-separated list of <field>:<direction> pairs.
     * $params['stats']                  = (array) Specific `tag` of the request for logging and statistical purposes.
     * $params['terminate_after']        = (integer) Maximum number of documents to collect for each shard. If a query reaches this limit, OpenSearch terminates the query early. OpenSearch collects documents before sorting. Use with caution. OpenSearch applies this parameter to each shard handling the request. When possible, let OpenSearch perform early termination automatically. Avoid specifying this parameter for requests that target data streams with backing indexes across multiple data tiers.
     * $params['timeout']                = (string) Period each update request waits for the following operations: dynamic mapping updates, waiting for active shards.
     * $params['version']                = (boolean) If `true`, returns the document version as part of a hit.
     * $params['wait_for_active_shards'] = (any) The number of shard copies that must be active before proceeding with the operation. Set to `all` or any positive integer up to the total number of shards in the index (`number_of_replicas+1`).
     * $params['wait_for_completion']    = (boolean) If `true`, the request blocks until the operation is complete. (Default = true)
     * $params['pretty']                 = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']                  = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']            = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']                 = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']            = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     * $params['body']                   = (array) The search definition using the Query DSL
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function updateByQuery(array $params = [])
    {
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $this->endpointFactory->getEndpoint(UpdateByQuery::class);
        $endpoint->setParams($params);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }

    /**
     * Changes the number of requests per second for a particular Update By Query operation.
     *
     * $params['task_id']             = (string) The ID for the task. (Required)
     * $params['requests_per_second'] = (number) The throttle for this request in sub-requests per second.
     * $params['pretty']              = (boolean) Whether to pretty-format the returned JSON response. (Default = false)
     * $params['human']               = (boolean) Whether to return human-readable values for statistics. (Default = false)
     * $params['error_trace']         = (boolean) Whether to include the stack trace of returned errors. (Default = false)
     * $params['source']              = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
     * $params['filter_path']         = (any) A comma-separated list of filters used to filter the response. Use wildcards to match any field or part of a field's name. To exclude fields, use `-`.
     *
     * @param array $params Associative array of parameters
     * @return array
     */
    public function updateByQueryRethrottle(array $params = [])
    {
        $task_id = $this->extractArgument($params, 'task_id');

        $endpoint = $this->endpointFactory->getEndpoint(UpdateByQueryRethrottle::class);
        $endpoint->setParams($params);
        $endpoint->setTaskId($task_id);

        return $this->performRequest($endpoint);
    }

    /**
     * Proxy function to createPointInTime() to prevent BC break.
     * This API will be removed in a future version. Use 'createPit' API instead.
     */
    public function createPointInTime(array $params = [])
    {
        return $this->createPit($params);
    }
    /**
         * Creates a new document in the index.Returns a 409 response when a document with a same ID already exists in the index.
         *
         * $params['id']                     = (string) Unique identifier for the document. (Required)
         * $params['index']                  = (string) Name of the data stream or index to target. If the target doesn’t exist and matches the name or wildcard (`*`) pattern of an index template with a `data_stream` definition, this request creates the data stream. If the target doesn’t exist and doesn’t match a data stream template, this request creates the index. (Required)
         * $params['pipeline']               = (string) ID of the pipeline to use to preprocess incoming documents.If the index has a default ingest pipeline specified, then setting the value to `_none` disables the default ingest pipeline for this request.If a final pipeline is configured it will always run, regardless of the value of this parameter.
         * $params['refresh']                = (enum) If `true`, OpenSearch refreshes the affected shards to make this operation visible to search, if `wait_for` then wait for a refresh to make this operation visible to search, if `false` do nothing with refreshes.Valid values: `true`, `false`, `wait_for`. (Options = true,false,wait_for)
         * $params['routing']                = (string) Custom value used to route operations to a specific shard.
         * $params['timeout']                = (string) Period the request waits for the following operations: automatic index creation, dynamic mapping updates, waiting for active shards.
         * $params['version']                = (number) Explicit version number for concurrency control.The specified version must match the current version of the document for the request to succeed.
         * $params['version_type']           = (enum) Specific version type: `external`, `external_gte`. (Options = internal,external,external_gte,force)
         * $params['wait_for_active_shards'] = (any) The number of shard copies that must be active before proceeding with the operation.Set to `all` or any positive integer up to the total number of shards in the index (`number_of_replicas+1`).
         * $params['pretty']                 = (boolean) Whether to pretty format the returned JSON response.
         * $params['human']                  = (boolean) Whether to return human readable values for statistics.
         * $params['error_trace']            = (boolean) Whether to include the stack trace of returned errors.
         * $params['source']                 = (string) The URL-encoded request definition. Useful for libraries that do not accept a request body for non-POST requests.
         * $params['filter_path']            = (any) Comma-separated list of filters used to reduce the response.
         * $params['body']                   = (array) The document (Required)
         *
         * @param array $params Associative array of parameters
         * @return array
         */
    public function create(array $params = [])
    {
        $id = $this->extractArgument($params, 'id');
        $index = $this->extractArgument($params, 'index');
        $body = $this->extractArgument($params, 'body');

        $endpoint = $id ?
            $this->endpointFactory->getEndpoint(Create::class)
            : $this->endpointFactory->getEndpoint(Index::class);
        $endpoint->setParams($params);
        $endpoint->setId($id);
        $endpoint->setIndex($index);
        $endpoint->setBody($body);

        return $this->performRequest($endpoint);
    }
    /**
     * Proxy function to deletePointInTime() to prevent BC break.
     * This API will be removed in a future version. Use 'deletePit' API instead.
     */
    public function deletePointInTime(array $params = [])
    {
        return $this->deletePit($params);
    }
    /**
     * Returns the asyncSearch namespace
     *
     * @deprecated in 2.4.2 and will be removed in 3.0.0.
     */
    public function asyncSearch(): AsyncSearchNamespace
    {
        @trigger_error(__METHOD__ . '() is deprecated since 2.4.2 and will be removed in 3.0.0.', E_USER_DEPRECATED);
        return $this->asyncSearch;
    }
    /**
     * Returns the asynchronousSearch namespace
     */
    public function asynchronousSearch(): AsynchronousSearchNamespace
    {
        return $this->asynchronousSearch;
    }
    /**
     * Returns the cat namespace
     */
    public function cat(): CatNamespace
    {
        return $this->cat;
    }
    /**
     * Returns the cluster namespace
     */
    public function cluster(): ClusterNamespace
    {
        return $this->cluster;
    }
    /**
     * Returns the danglingIndices namespace
     */
    public function danglingIndices(): DanglingIndicesNamespace
    {
        return $this->danglingIndices;
    }
    /**
     * Returns the dataFrameTransformDeprecated namespace
     *
     * @deprecated in 2.4.2 and will be removed in 3.0.0.
     */
    public function dataFrameTransformDeprecated(): DataFrameTransformDeprecatedNamespace
    {
        @trigger_error(__METHOD__ . '() is deprecated since 2.4.2 and will be removed in 3.0.0.', E_USER_DEPRECATED);
        return $this->dataFrameTransformDeprecated;
    }
    /**
     * Returns the flowFramework namespace
     */
    public function flowFramework(): FlowFrameworkNamespace
    {
        return $this->flowFramework;
    }
    /**
     * Returns the geospatial namespace
     */
    public function geospatial(): GeospatialNamespace
    {
        return $this->geospatial;
    }
    /**
     * Returns the indices namespace
     */
    public function indices(): IndicesNamespace
    {
        return $this->indices;
    }
    /**
     * Returns the ingest namespace
     */
    public function ingest(): IngestNamespace
    {
        return $this->ingest;
    }
    /**
     * Returns the ingestion namespace
     */
    public function ingestion(): IngestionNamespace
    {
        return $this->ingestion;
    }
    /**
     * Returns the insights namespace
     */
    public function insights(): InsightsNamespace
    {
        return $this->insights;
    }
    /**
     * Returns the ism namespace
     */
    public function ism(): IsmNamespace
    {
        return $this->ism;
    }
    /**
     * Returns the knn namespace
     */
    public function knn(): KnnNamespace
    {
        return $this->knn;
    }
    /**
     * Returns the list namespace
     */
    public function list(): ListNamespace
    {
        return $this->list;
    }
    /**
     * Returns the ltr namespace
     */
    public function ltr(): LtrNamespace
    {
        return $this->ltr;
    }
    /**
     * Returns the ml namespace
     */
    public function ml(): MlNamespace
    {
        return $this->ml;
    }
    /**
     * Returns the monitoring namespace
     *
     * @deprecated in 2.4.2 and will be removed in 3.0.0.
     */
    public function monitoring(): MonitoringNamespace
    {
        @trigger_error(__METHOD__ . '() is deprecated since 2.4.2 and will be removed in 3.0.0.', E_USER_DEPRECATED);
        return $this->monitoring;
    }
    /**
     * Returns the neural namespace
     */
    public function neural(): NeuralNamespace
    {
        return $this->neural;
    }
    /**
     * Returns the nodes namespace
     */
    public function nodes(): NodesNamespace
    {
        return $this->nodes;
    }
    /**
     * Returns the notifications namespace
     */
    public function notifications(): NotificationsNamespace
    {
        return $this->notifications;
    }
    /**
     * Returns the observability namespace
     */
    public function observability(): ObservabilityNamespace
    {
        return $this->observability;
    }
    /**
     * Returns the ppl namespace
     */
    public function ppl(): PplNamespace
    {
        return $this->ppl;
    }
    /**
     * Returns the query namespace
     */
    public function query(): QueryNamespace
    {
        return $this->query;
    }
    /**
     * Returns the remoteStore namespace
     */
    public function remoteStore(): RemoteStoreNamespace
    {
        return $this->remoteStore;
    }
    /**
     * Returns the replication namespace
     */
    public function replication(): ReplicationNamespace
    {
        return $this->replication;
    }
    /**
     * Returns the rollups namespace
     */
    public function rollups(): RollupsNamespace
    {
        return $this->rollups;
    }
    /**
     * Returns the searchPipeline namespace
     */
    public function searchPipeline(): SearchPipelineNamespace
    {
        return $this->searchPipeline;
    }
    /**
     * Returns the searchRelevance namespace
     */
    public function searchRelevance(): SearchRelevanceNamespace
    {
        return $this->searchRelevance;
    }
    /**
     * Returns the searchableSnapshots namespace
     *
     * @deprecated in 2.4.2 and will be removed in 3.0.0.
     */
    public function searchableSnapshots(): SearchableSnapshotsNamespace
    {
        @trigger_error(__METHOD__ . '() is deprecated since 2.4.2 and will be removed in 3.0.0.', E_USER_DEPRECATED);
        return $this->searchableSnapshots;
    }
    /**
     * Returns the security namespace
     */
    public function security(): SecurityNamespace
    {
        return $this->security;
    }
    /**
     * Returns the securityAnalytics namespace
     */
    public function securityAnalytics(): SecurityAnalyticsNamespace
    {
        return $this->securityAnalytics;
    }
    /**
     * Returns the sm namespace
     */
    public function sm(): SmNamespace
    {
        return $this->sm;
    }
    /**
     * Returns the snapshot namespace
     */
    public function snapshot(): SnapshotNamespace
    {
        return $this->snapshot;
    }
    /**
     * Returns the sql namespace
     */
    public function sql(): SqlNamespace
    {
        return $this->sql;
    }
    /**
     * Returns the ssl namespace
     *
     * @deprecated in 2.4.2 and will be removed in 3.0.0.
     */
    public function ssl(): SslNamespace
    {
        @trigger_error(__METHOD__ . '() is deprecated since 2.4.2 and will be removed in 3.0.0.', E_USER_DEPRECATED);
        return $this->ssl;
    }
    /**
     * Returns the tasks namespace
     */
    public function tasks(): TasksNamespace
    {
        return $this->tasks;
    }
    /**
     * Returns the transforms namespace
     */
    public function transforms(): TransformsNamespace
    {
        return $this->transforms;
    }
    /**
     * Returns the ubi namespace
     */
    public function ubi(): UbiNamespace
    {
        return $this->ubi;
    }
    /**
     * Returns the wlm namespace
     */
    public function wlm(): WlmNamespace
    {
        return $this->wlm;
    }

    /**
     * Gets the endpoint factory.
     */
    protected function getEndpointFactory(): EndpointFactoryInterface
    {
        return $this->endpointFactory;
    }

    /**
     * Catchall for registered namespaces
     *
     * @return object
     * @throws \BadMethodCallException if the namespace cannot be found
     */
    public function __call(string $name, array $arguments)
    {
        if (isset($this->registeredNamespaces[$name])) {
            return $this->registeredNamespaces[$name];
        }
        throw new \BadMethodCallException("Namespace [$name] not found");
    }

    /**
     * Extract an argument from the array of parameters
     *
     * @return null|mixed
     */
    public function extractArgument(array &$params, string $arg)
    {
        if (array_key_exists($arg, $params) === true) {
            $value = $params[$arg];
            $value = (is_object($value) && !is_iterable($value)) ?
                (array) $value :
                $value;
            unset($params[$arg]);
            return $value;
        } else {
            return null;
        }
    }

    /**
     * Send a raw request to the cluster.
     *
     * @throws \Psr\Http\Client\ClientExceptionInterface
     * @throws \OpenSearch\Exception\HttpExceptionInterface
     */
    public function request(
        string $method,
        string $uri,
        array $attributes = []
    ): iterable|string|null {
        $params = $attributes['params'] ?? [];
        $body = $attributes['body'] ?? null;
        $options = $attributes['options'] ?? [];

        return $this->httpTransport->sendRequest($method, $uri, $params, $body, $options['headers'] ?? []);
    }

    /**
     * Send a request for an endpoint.
     *
     * @throws \Psr\Http\Client\ClientExceptionInterface
     * @throws \OpenSearch\Exception\HttpExceptionInterface
     */
    private function performRequest(AbstractEndpoint $endpoint): iterable|string|null
    {
        return $this->httpTransport->sendRequest(
            $endpoint->getMethod(),
            $endpoint->getURI(),
            $endpoint->getParams(),
            $endpoint->getBody(),
            $endpoint->getOptions()
        );
    }

}
