/*
 * Copyright Elasticsearch B.V. and contributors
 * SPDX-License-Identifier: Apache-2.0
 */

// This file was automatically generated by elastic/elastic-client-generator-js
// DO NOT MODIFY IT BY HAND. Instead, modify the source open api file,
// and elastic/elastic-client-generator-js to regenerate this file again.

import {
  Transport,
  TransportRequestMetadata,
  TransportRequestOptions,
  TransportRequestOptionsWithMeta,
  TransportRequestOptionsWithOutMeta,
  TransportResult
} from '@elastic/transport'
import * as T from '../types'
import { kAcceptedParams } from '../../symbols'

interface That {
  transport: Transport
  [kAcceptedParams]: Record<string, { path: string[], body: string[], query: string[] }>
}

const commonQueryParams = ['error_trace', 'filter_path', 'human', 'pretty']

export default class Fleet {
  transport: Transport
  [kAcceptedParams]: Record<string, { path: string[], body: string[], query: string[] }>
  constructor (transport: Transport) {
    this.transport = transport
    this[kAcceptedParams] = {
      'fleet.delete_secret': {
        path: [
          'id'
        ],
        body: [],
        query: []
      },
      'fleet.get_secret': {
        path: [
          'id'
        ],
        body: [],
        query: []
      },
      'fleet.global_checkpoints': {
        path: [
          'index'
        ],
        body: [],
        query: [
          'wait_for_advance',
          'wait_for_index',
          'checkpoints',
          'timeout'
        ]
      },
      'fleet.msearch': {
        path: [
          'index'
        ],
        body: [
          'searches'
        ],
        query: [
          'allow_no_indices',
          'ccs_minimize_roundtrips',
          'expand_wildcards',
          'ignore_throttled',
          'ignore_unavailable',
          'max_concurrent_searches',
          'max_concurrent_shard_requests',
          'pre_filter_shard_size',
          'search_type',
          'rest_total_hits_as_int',
          'typed_keys',
          'wait_for_checkpoints',
          'allow_partial_search_results'
        ]
      },
      'fleet.post_secret': {
        path: [],
        body: [
          'value'
        ],
        query: []
      },
      'fleet.search': {
        path: [
          'index'
        ],
        body: [
          'aggregations',
          'aggs',
          'collapse',
          'explain',
          'ext',
          'from',
          'highlight',
          'track_total_hits',
          'indices_boost',
          'docvalue_fields',
          'min_score',
          'post_filter',
          'profile',
          'query',
          'rescore',
          'script_fields',
          'search_after',
          'size',
          'slice',
          'sort',
          '_source',
          'fields',
          'suggest',
          'terminate_after',
          'timeout',
          'track_scores',
          'version',
          'seq_no_primary_term',
          'stored_fields',
          'pit',
          'runtime_mappings',
          'stats'
        ],
        query: [
          'allow_no_indices',
          'analyzer',
          'analyze_wildcard',
          'batched_reduce_size',
          'ccs_minimize_roundtrips',
          'default_operator',
          'df',
          'docvalue_fields',
          'expand_wildcards',
          'explain',
          'ignore_throttled',
          'ignore_unavailable',
          'lenient',
          'max_concurrent_shard_requests',
          'preference',
          'pre_filter_shard_size',
          'request_cache',
          'routing',
          'scroll',
          'search_type',
          'stats',
          'stored_fields',
          'suggest_field',
          'suggest_mode',
          'suggest_size',
          'suggest_text',
          'terminate_after',
          'timeout',
          'track_total_hits',
          'track_scores',
          'typed_keys',
          'rest_total_hits_as_int',
          'version',
          '_source',
          '_source_excludes',
          '_source_includes',
          'seq_no_primary_term',
          'q',
          'size',
          'from',
          'sort',
          'wait_for_checkpoints',
          'allow_partial_search_results'
        ]
      }
    }
  }

  /**
    * Deletes a secret stored by Fleet.
    */
  async deleteSecret (this: That, params: T.FleetDeleteSecretRequest, options?: TransportRequestOptionsWithOutMeta): Promise<T.FleetDeleteSecretResponse>
  async deleteSecret (this: That, params: T.FleetDeleteSecretRequest, options?: TransportRequestOptionsWithMeta): Promise<TransportResult<T.FleetDeleteSecretResponse, unknown>>
  async deleteSecret (this: That, params: T.FleetDeleteSecretRequest, options?: TransportRequestOptions): Promise<T.FleetDeleteSecretResponse>
  async deleteSecret (this: That, params: T.FleetDeleteSecretRequest, options?: TransportRequestOptions): Promise<any> {
    const {
      path: acceptedPath
    } = this[kAcceptedParams]['fleet.delete_secret']

    const userQuery = params?.querystring
    const querystring: Record<string, any> = userQuery != null ? { ...userQuery } : {}

    let body: Record<string, any> | string | undefined
    const userBody = params?.body
    if (userBody != null) {
      if (typeof userBody === 'string') {
        body = userBody
      } else {
        body = { ...userBody }
      }
    }

    for (const key in params) {
      if (acceptedPath.includes(key)) {
        continue
      } else if (key !== 'body' && key !== 'querystring') {
        // @ts-expect-error
        querystring[key] = params[key]
      }
    }

    const method = 'DELETE'
    const path = `/_fleet/secret/${encodeURIComponent(params.id.toString())}`
    const meta: TransportRequestMetadata = {
      name: 'fleet.delete_secret',
      pathParts: {
        id: params.id
      },
      acceptedParams: {
        path: ['id'],
        body: [],
        query: []
      }
    }
    return await this.transport.request({ path, method, querystring, body, meta }, options)
  }

  /**
    * Retrieves a secret stored by Fleet.
    */
  async getSecret (this: That, params: T.FleetGetSecretRequest, options?: TransportRequestOptionsWithOutMeta): Promise<T.FleetGetSecretResponse>
  async getSecret (this: That, params: T.FleetGetSecretRequest, options?: TransportRequestOptionsWithMeta): Promise<TransportResult<T.FleetGetSecretResponse, unknown>>
  async getSecret (this: That, params: T.FleetGetSecretRequest, options?: TransportRequestOptions): Promise<T.FleetGetSecretResponse>
  async getSecret (this: That, params: T.FleetGetSecretRequest, options?: TransportRequestOptions): Promise<any> {
    const {
      path: acceptedPath
    } = this[kAcceptedParams]['fleet.get_secret']

    const userQuery = params?.querystring
    const querystring: Record<string, any> = userQuery != null ? { ...userQuery } : {}

    let body: Record<string, any> | string | undefined
    const userBody = params?.body
    if (userBody != null) {
      if (typeof userBody === 'string') {
        body = userBody
      } else {
        body = { ...userBody }
      }
    }

    for (const key in params) {
      if (acceptedPath.includes(key)) {
        continue
      } else if (key !== 'body' && key !== 'querystring') {
        // @ts-expect-error
        querystring[key] = params[key]
      }
    }

    const method = 'GET'
    const path = `/_fleet/secret/${encodeURIComponent(params.id.toString())}`
    const meta: TransportRequestMetadata = {
      name: 'fleet.get_secret',
      pathParts: {
        id: params.id
      },
      acceptedParams: {
        path: ['id'],
        body: [],
        query: []
      }
    }
    return await this.transport.request({ path, method, querystring, body, meta }, options)
  }

  /**
    * Get global checkpoints. Get the current global checkpoints for an index. This API is designed for internal use by the Fleet server project.
    * @see {@link https://www.elastic.co/docs/api/doc/elasticsearch/group/endpoint-fleet | Elasticsearch API documentation}
    */
  async globalCheckpoints (this: That, params: T.FleetGlobalCheckpointsRequest, options?: TransportRequestOptionsWithOutMeta): Promise<T.FleetGlobalCheckpointsResponse>
  async globalCheckpoints (this: That, params: T.FleetGlobalCheckpointsRequest, options?: TransportRequestOptionsWithMeta): Promise<TransportResult<T.FleetGlobalCheckpointsResponse, unknown>>
  async globalCheckpoints (this: That, params: T.FleetGlobalCheckpointsRequest, options?: TransportRequestOptions): Promise<T.FleetGlobalCheckpointsResponse>
  async globalCheckpoints (this: That, params: T.FleetGlobalCheckpointsRequest, options?: TransportRequestOptions): Promise<any> {
    const {
      path: acceptedPath
    } = this[kAcceptedParams]['fleet.global_checkpoints']

    const userQuery = params?.querystring
    const querystring: Record<string, any> = userQuery != null ? { ...userQuery } : {}

    let body: Record<string, any> | string | undefined
    const userBody = params?.body
    if (userBody != null) {
      if (typeof userBody === 'string') {
        body = userBody
      } else {
        body = { ...userBody }
      }
    }

    for (const key in params) {
      if (acceptedPath.includes(key)) {
        continue
      } else if (key !== 'body' && key !== 'querystring') {
        // @ts-expect-error
        querystring[key] = params[key]
      }
    }

    const method = 'GET'
    const path = `/${encodeURIComponent(params.index.toString())}/_fleet/global_checkpoints`
    const meta: TransportRequestMetadata = {
      name: 'fleet.global_checkpoints',
      pathParts: {
        index: params.index
      },
      acceptedParams: {
        path: ['index'],
        body: [],
        query: ['wait_for_advance', 'wait_for_index', 'checkpoints', 'timeout']
      }
    }
    return await this.transport.request({ path, method, querystring, body, meta }, options)
  }

  /**
    * Run multiple Fleet searches. Run several Fleet searches with a single API request. The API follows the same structure as the multi search API. However, similar to the Fleet search API, it supports the `wait_for_checkpoints` parameter.
    * @see {@link https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-fleet-msearch | Elasticsearch API documentation}
    */
  async msearch<TDocument = unknown> (this: That, params: T.FleetMsearchRequest, options?: TransportRequestOptionsWithOutMeta): Promise<T.FleetMsearchResponse<TDocument>>
  async msearch<TDocument = unknown> (this: That, params: T.FleetMsearchRequest, options?: TransportRequestOptionsWithMeta): Promise<TransportResult<T.FleetMsearchResponse<TDocument>, unknown>>
  async msearch<TDocument = unknown> (this: That, params: T.FleetMsearchRequest, options?: TransportRequestOptions): Promise<T.FleetMsearchResponse<TDocument>>
  async msearch<TDocument = unknown> (this: That, params: T.FleetMsearchRequest, options?: TransportRequestOptions): Promise<any> {
    const {
      path: acceptedPath,
      body: acceptedBody,
      query: acceptedQuery
    } = this[kAcceptedParams]['fleet.msearch']

    const userQuery = params?.querystring
    const querystring: Record<string, any> = userQuery != null ? { ...userQuery } : {}

    let body: any = params.body ?? undefined
    for (const key in params) {
      if (acceptedBody.includes(key)) {
        // @ts-expect-error
        body = params[key]
      } else if (acceptedPath.includes(key)) {
        continue
      } else if (key !== 'body' && key !== 'querystring') {
        if (acceptedQuery.includes(key) || commonQueryParams.includes(key)) {
          // @ts-expect-error
          querystring[key] = params[key]
        } else {
          body = body ?? {}
          // @ts-expect-error
          body[key] = params[key]
        }
      }
    }

    let method = ''
    let path = ''
    if (params.index != null) {
      method = body != null ? 'POST' : 'GET'
      path = `/${encodeURIComponent(params.index.toString())}/_fleet/_fleet_msearch`
    } else {
      method = body != null ? 'POST' : 'GET'
      path = '/_fleet/_fleet_msearch'
    }
    const meta: TransportRequestMetadata = {
      name: 'fleet.msearch',
      pathParts: {
        index: params.index
      },
      acceptedParams: {
        path: ['index'],
        body: ['searches'],
        query: ['allow_no_indices', 'ccs_minimize_roundtrips', 'expand_wildcards', 'ignore_throttled', 'ignore_unavailable', 'max_concurrent_searches', 'max_concurrent_shard_requests', 'pre_filter_shard_size', 'search_type', 'rest_total_hits_as_int', 'typed_keys', 'wait_for_checkpoints', 'allow_partial_search_results']
      }
    }
    return await this.transport.request({ path, method, querystring, bulkBody: body, meta }, options)
  }

  /**
    * Creates a secret stored by Fleet.
    */
  async postSecret (this: That, params: T.FleetPostSecretRequest, options?: TransportRequestOptionsWithOutMeta): Promise<T.FleetPostSecretResponse>
  async postSecret (this: That, params: T.FleetPostSecretRequest, options?: TransportRequestOptionsWithMeta): Promise<TransportResult<T.FleetPostSecretResponse, unknown>>
  async postSecret (this: That, params: T.FleetPostSecretRequest, options?: TransportRequestOptions): Promise<T.FleetPostSecretResponse>
  async postSecret (this: That, params: T.FleetPostSecretRequest, options?: TransportRequestOptions): Promise<any> {
    const {
      path: acceptedPath,
      body: acceptedBody,
      query: acceptedQuery
    } = this[kAcceptedParams]['fleet.post_secret']

    const userQuery = params?.querystring
    const querystring: Record<string, any> = userQuery != null ? { ...userQuery } : {}

    let body: Record<string, any> | string | undefined
    const userBody = params?.body
    if (userBody != null) {
      if (typeof userBody === 'string') {
        body = userBody
      } else {
        body = { ...userBody }
      }
    }

    for (const key in params) {
      if (acceptedBody.includes(key)) {
        body = body ?? {}
        // @ts-expect-error
        body[key] = params[key]
      } else if (acceptedPath.includes(key)) {
        continue
      } else if (key !== 'body' && key !== 'querystring') {
        if (acceptedQuery.includes(key) || commonQueryParams.includes(key)) {
          // @ts-expect-error
          querystring[key] = params[key]
        } else {
          body = body ?? {}
          // @ts-expect-error
          body[key] = params[key]
        }
      }
    }

    const method = 'POST'
    const path = '/_fleet/secret'
    const meta: TransportRequestMetadata = {
      name: 'fleet.post_secret',
      acceptedParams: {
        path: [],
        body: ['value'],
        query: []
      }
    }
    return await this.transport.request({ path, method, querystring, body, meta }, options)
  }

  /**
    * Run a Fleet search. The purpose of the Fleet search API is to provide an API where the search will be run only after the provided checkpoint has been processed and is visible for searches inside of Elasticsearch.
    * @see {@link https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-fleet-search | Elasticsearch API documentation}
    */
  async search<TDocument = unknown> (this: That, params: T.FleetSearchRequest, options?: TransportRequestOptionsWithOutMeta): Promise<T.FleetSearchResponse<TDocument>>
  async search<TDocument = unknown> (this: That, params: T.FleetSearchRequest, options?: TransportRequestOptionsWithMeta): Promise<TransportResult<T.FleetSearchResponse<TDocument>, unknown>>
  async search<TDocument = unknown> (this: That, params: T.FleetSearchRequest, options?: TransportRequestOptions): Promise<T.FleetSearchResponse<TDocument>>
  async search<TDocument = unknown> (this: That, params: T.FleetSearchRequest, options?: TransportRequestOptions): Promise<any> {
    const {
      path: acceptedPath,
      body: acceptedBody,
      query: acceptedQuery
    } = this[kAcceptedParams]['fleet.search']

    const userQuery = params?.querystring
    const querystring: Record<string, any> = userQuery != null ? { ...userQuery } : {}

    let body: Record<string, any> | string | undefined
    const userBody = params?.body
    if (userBody != null) {
      if (typeof userBody === 'string') {
        body = userBody
      } else {
        body = { ...userBody }
      }
    }

    for (const key in params) {
      if (acceptedBody.includes(key)) {
        body = body ?? {}
        // @ts-expect-error
        body[key] = params[key]
      } else if (acceptedPath.includes(key)) {
        continue
      } else if (key !== 'body' && key !== 'querystring') {
        if (acceptedQuery.includes(key) || commonQueryParams.includes(key)) {
          // @ts-expect-error
          querystring[key] = params[key]
        } else {
          body = body ?? {}
          // @ts-expect-error
          body[key] = params[key]
        }
      }
    }

    const method = body != null ? 'POST' : 'GET'
    const path = `/${encodeURIComponent(params.index.toString())}/_fleet/_fleet_search`
    const meta: TransportRequestMetadata = {
      name: 'fleet.search',
      pathParts: {
        index: params.index
      },
      acceptedParams: {
        path: ['index'],
        body: ['aggregations', 'aggs', 'collapse', 'explain', 'ext', 'from', 'highlight', 'track_total_hits', 'indices_boost', 'docvalue_fields', 'min_score', 'post_filter', 'profile', 'query', 'rescore', 'script_fields', 'search_after', 'size', 'slice', 'sort', '_source', 'fields', 'suggest', 'terminate_after', 'timeout', 'track_scores', 'version', 'seq_no_primary_term', 'stored_fields', 'pit', 'runtime_mappings', 'stats'],
        query: ['allow_no_indices', 'analyzer', 'analyze_wildcard', 'batched_reduce_size', 'ccs_minimize_roundtrips', 'default_operator', 'df', 'docvalue_fields', 'expand_wildcards', 'explain', 'ignore_throttled', 'ignore_unavailable', 'lenient', 'max_concurrent_shard_requests', 'preference', 'pre_filter_shard_size', 'request_cache', 'routing', 'scroll', 'search_type', 'stats', 'stored_fields', 'suggest_field', 'suggest_mode', 'suggest_size', 'suggest_text', 'terminate_after', 'timeout', 'track_total_hits', 'track_scores', 'typed_keys', 'rest_total_hits_as_int', 'version', '_source', '_source_excludes', '_source_includes', 'seq_no_primary_term', 'q', 'size', 'from', 'sort', 'wait_for_checkpoints', 'allow_partial_search_results']
      }
    }
    return await this.transport.request({ path, method, querystring, body, meta }, options)
  }
}
