/*
 * 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 Rollup {
  transport: Transport
  [kAcceptedParams]: Record<string, { path: string[], body: string[], query: string[] }>
  constructor (transport: Transport) {
    this.transport = transport
    this[kAcceptedParams] = {
      'rollup.delete_job': {
        path: [
          'id'
        ],
        body: [],
        query: []
      },
      'rollup.get_jobs': {
        path: [
          'id'
        ],
        body: [],
        query: []
      },
      'rollup.get_rollup_caps': {
        path: [
          'id'
        ],
        body: [],
        query: []
      },
      'rollup.get_rollup_index_caps': {
        path: [
          'index'
        ],
        body: [],
        query: []
      },
      'rollup.put_job': {
        path: [
          'id'
        ],
        body: [
          'cron',
          'groups',
          'index_pattern',
          'metrics',
          'page_size',
          'rollup_index',
          'timeout',
          'headers'
        ],
        query: []
      },
      'rollup.rollup_search': {
        path: [
          'index'
        ],
        body: [
          'aggregations',
          'aggs',
          'query',
          'size'
        ],
        query: [
          'rest_total_hits_as_int',
          'typed_keys'
        ]
      },
      'rollup.start_job': {
        path: [
          'id'
        ],
        body: [],
        query: []
      },
      'rollup.stop_job': {
        path: [
          'id'
        ],
        body: [],
        query: [
          'timeout',
          'wait_for_completion'
        ]
      }
    }
  }

  /**
    * Delete a rollup job. A job must be stopped before it can be deleted. If you attempt to delete a started job, an error occurs. Similarly, if you attempt to delete a nonexistent job, an exception occurs. IMPORTANT: When you delete a job, you remove only the process that is actively monitoring and rolling up data. The API does not delete any previously rolled up data. This is by design; a user may wish to roll up a static data set. Because the data set is static, after it has been fully rolled up there is no need to keep the indexing rollup job around (as there will be no new data). Thus the job can be deleted, leaving behind the rolled up data for analysis. If you wish to also remove the rollup data and the rollup index contains the data for only a single job, you can delete the whole rollup index. If the rollup index stores data from several jobs, you must issue a delete-by-query that targets the rollup job's identifier in the rollup index. For example: ``` POST my_rollup_index/_delete_by_query { "query": { "term": { "_rollup.id": "the_rollup_job_id" } } } ```
    * @see {@link https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-rollup-delete-job | Elasticsearch API documentation}
    */
  async deleteJob (this: That, params: T.RollupDeleteJobRequest, options?: TransportRequestOptionsWithOutMeta): Promise<T.RollupDeleteJobResponse>
  async deleteJob (this: That, params: T.RollupDeleteJobRequest, options?: TransportRequestOptionsWithMeta): Promise<TransportResult<T.RollupDeleteJobResponse, unknown>>
  async deleteJob (this: That, params: T.RollupDeleteJobRequest, options?: TransportRequestOptions): Promise<T.RollupDeleteJobResponse>
  async deleteJob (this: That, params: T.RollupDeleteJobRequest, options?: TransportRequestOptions): Promise<any> {
    const {
      path: acceptedPath
    } = this[kAcceptedParams]['rollup.delete_job']

    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 = `/_rollup/job/${encodeURIComponent(params.id.toString())}`
    const meta: TransportRequestMetadata = {
      name: 'rollup.delete_job',
      pathParts: {
        id: params.id
      },
      acceptedParams: {
        path: ['id'],
        body: [],
        query: []
      }
    }
    return await this.transport.request({ path, method, querystring, body, meta }, options)
  }

  /**
    * Get rollup job information. Get the configuration, stats, and status of rollup jobs. NOTE: This API returns only active (both `STARTED` and `STOPPED`) jobs. If a job was created, ran for a while, then was deleted, the API does not return any details about it. For details about a historical rollup job, the rollup capabilities API may be more useful.
    * @see {@link https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-rollup-get-jobs | Elasticsearch API documentation}
    */
  async getJobs (this: That, params?: T.RollupGetJobsRequest, options?: TransportRequestOptionsWithOutMeta): Promise<T.RollupGetJobsResponse>
  async getJobs (this: That, params?: T.RollupGetJobsRequest, options?: TransportRequestOptionsWithMeta): Promise<TransportResult<T.RollupGetJobsResponse, unknown>>
  async getJobs (this: That, params?: T.RollupGetJobsRequest, options?: TransportRequestOptions): Promise<T.RollupGetJobsResponse>
  async getJobs (this: That, params?: T.RollupGetJobsRequest, options?: TransportRequestOptions): Promise<any> {
    const {
      path: acceptedPath
    } = this[kAcceptedParams]['rollup.get_jobs']

    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 }
      }
    }

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

    let method = ''
    let path = ''
    if (params.id != null) {
      method = 'GET'
      path = `/_rollup/job/${encodeURIComponent(params.id.toString())}`
    } else {
      method = 'GET'
      path = '/_rollup/job'
    }
    const meta: TransportRequestMetadata = {
      name: 'rollup.get_jobs',
      pathParts: {
        id: params.id
      },
      acceptedParams: {
        path: ['id'],
        body: [],
        query: []
      }
    }
    return await this.transport.request({ path, method, querystring, body, meta }, options)
  }

  /**
    * Get the rollup job capabilities. Get the capabilities of any rollup jobs that have been configured for a specific index or index pattern. This API is useful because a rollup job is often configured to rollup only a subset of fields from the source index. Furthermore, only certain aggregations can be configured for various fields, leading to a limited subset of functionality depending on that configuration. This API enables you to inspect an index and determine: 1. Does this index have associated rollup data somewhere in the cluster? 2. If yes to the first question, what fields were rolled up, what aggregations can be performed, and where does the data live?
    * @see {@link https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-rollup-get-rollup-caps | Elasticsearch API documentation}
    */
  async getRollupCaps (this: That, params?: T.RollupGetRollupCapsRequest, options?: TransportRequestOptionsWithOutMeta): Promise<T.RollupGetRollupCapsResponse>
  async getRollupCaps (this: That, params?: T.RollupGetRollupCapsRequest, options?: TransportRequestOptionsWithMeta): Promise<TransportResult<T.RollupGetRollupCapsResponse, unknown>>
  async getRollupCaps (this: That, params?: T.RollupGetRollupCapsRequest, options?: TransportRequestOptions): Promise<T.RollupGetRollupCapsResponse>
  async getRollupCaps (this: That, params?: T.RollupGetRollupCapsRequest, options?: TransportRequestOptions): Promise<any> {
    const {
      path: acceptedPath
    } = this[kAcceptedParams]['rollup.get_rollup_caps']

    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 }
      }
    }

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

    let method = ''
    let path = ''
    if (params.id != null) {
      method = 'GET'
      path = `/_rollup/data/${encodeURIComponent(params.id.toString())}`
    } else {
      method = 'GET'
      path = '/_rollup/data'
    }
    const meta: TransportRequestMetadata = {
      name: 'rollup.get_rollup_caps',
      pathParts: {
        id: params.id
      },
      acceptedParams: {
        path: ['id'],
        body: [],
        query: []
      }
    }
    return await this.transport.request({ path, method, querystring, body, meta }, options)
  }

  /**
    * Get the rollup index capabilities. Get the rollup capabilities of all jobs inside of a rollup index. A single rollup index may store the data for multiple rollup jobs and may have a variety of capabilities depending on those jobs. This API enables you to determine: * What jobs are stored in an index (or indices specified via a pattern)? * What target indices were rolled up, what fields were used in those rollups, and what aggregations can be performed on each job?
    * @see {@link https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-rollup-get-rollup-index-caps | Elasticsearch API documentation}
    */
  async getRollupIndexCaps (this: That, params: T.RollupGetRollupIndexCapsRequest, options?: TransportRequestOptionsWithOutMeta): Promise<T.RollupGetRollupIndexCapsResponse>
  async getRollupIndexCaps (this: That, params: T.RollupGetRollupIndexCapsRequest, options?: TransportRequestOptionsWithMeta): Promise<TransportResult<T.RollupGetRollupIndexCapsResponse, unknown>>
  async getRollupIndexCaps (this: That, params: T.RollupGetRollupIndexCapsRequest, options?: TransportRequestOptions): Promise<T.RollupGetRollupIndexCapsResponse>
  async getRollupIndexCaps (this: That, params: T.RollupGetRollupIndexCapsRequest, options?: TransportRequestOptions): Promise<any> {
    const {
      path: acceptedPath
    } = this[kAcceptedParams]['rollup.get_rollup_index_caps']

    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())}/_rollup/data`
    const meta: TransportRequestMetadata = {
      name: 'rollup.get_rollup_index_caps',
      pathParts: {
        index: params.index
      },
      acceptedParams: {
        path: ['index'],
        body: [],
        query: []
      }
    }
    return await this.transport.request({ path, method, querystring, body, meta }, options)
  }

  /**
    * Create a rollup job. WARNING: From 8.15.0, calling this API in a cluster with no rollup usage will fail with a message about the deprecation and planned removal of rollup features. A cluster needs to contain either a rollup job or a rollup index in order for this API to be allowed to run. The rollup job configuration contains all the details about how the job should run, when it indexes documents, and what future queries will be able to run against the rollup index. There are three main sections to the job configuration: the logistical details about the job (for example, the cron schedule), the fields that are used for grouping, and what metrics to collect for each group. Jobs are created in a `STOPPED` state. You can start them with the start rollup jobs API.
    * @see {@link https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-rollup-put-job | Elasticsearch API documentation}
    */
  async putJob (this: That, params: T.RollupPutJobRequest, options?: TransportRequestOptionsWithOutMeta): Promise<T.RollupPutJobResponse>
  async putJob (this: That, params: T.RollupPutJobRequest, options?: TransportRequestOptionsWithMeta): Promise<TransportResult<T.RollupPutJobResponse, unknown>>
  async putJob (this: That, params: T.RollupPutJobRequest, options?: TransportRequestOptions): Promise<T.RollupPutJobResponse>
  async putJob (this: That, params: T.RollupPutJobRequest, options?: TransportRequestOptions): Promise<any> {
    const {
      path: acceptedPath,
      body: acceptedBody,
      query: acceptedQuery
    } = this[kAcceptedParams]['rollup.put_job']

    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 = 'PUT'
    const path = `/_rollup/job/${encodeURIComponent(params.id.toString())}`
    const meta: TransportRequestMetadata = {
      name: 'rollup.put_job',
      pathParts: {
        id: params.id
      },
      acceptedParams: {
        path: ['id'],
        body: ['cron', 'groups', 'index_pattern', 'metrics', 'page_size', 'rollup_index', 'timeout', 'headers'],
        query: []
      }
    }
    return await this.transport.request({ path, method, querystring, body, meta }, options)
  }

  /**
    * Search rolled-up data. The rollup search endpoint is needed because, internally, rolled-up documents utilize a different document structure than the original data. It rewrites standard Query DSL into a format that matches the rollup documents then takes the response and rewrites it back to what a client would expect given the original query. The request body supports a subset of features from the regular search API. The following functionality is not available: `size`: Because rollups work on pre-aggregated data, no search hits can be returned and so size must be set to zero or omitted entirely. `highlighter`, `suggestors`, `post_filter`, `profile`, `explain`: These are similarly disallowed. For more detailed examples of using the rollup search API, including querying rolled-up data only or combining rolled-up and live data, refer to the External documentation.
    * @see {@link https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-rollup-rollup-search | Elasticsearch API documentation}
    */
  async rollupSearch<TDocument = unknown, TAggregations = Record<T.AggregateName, T.AggregationsAggregate>> (this: That, params: T.RollupRollupSearchRequest, options?: TransportRequestOptionsWithOutMeta): Promise<T.RollupRollupSearchResponse<TDocument, TAggregations>>
  async rollupSearch<TDocument = unknown, TAggregations = Record<T.AggregateName, T.AggregationsAggregate>> (this: That, params: T.RollupRollupSearchRequest, options?: TransportRequestOptionsWithMeta): Promise<TransportResult<T.RollupRollupSearchResponse<TDocument, TAggregations>, unknown>>
  async rollupSearch<TDocument = unknown, TAggregations = Record<T.AggregateName, T.AggregationsAggregate>> (this: That, params: T.RollupRollupSearchRequest, options?: TransportRequestOptions): Promise<T.RollupRollupSearchResponse<TDocument, TAggregations>>
  async rollupSearch<TDocument = unknown, TAggregations = Record<T.AggregateName, T.AggregationsAggregate>> (this: That, params: T.RollupRollupSearchRequest, options?: TransportRequestOptions): Promise<any> {
    const {
      path: acceptedPath,
      body: acceptedBody,
      query: acceptedQuery
    } = this[kAcceptedParams]['rollup.rollup_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())}/_rollup_search`
    const meta: TransportRequestMetadata = {
      name: 'rollup.rollup_search',
      pathParts: {
        index: params.index
      },
      acceptedParams: {
        path: ['index'],
        body: ['aggregations', 'aggs', 'query', 'size'],
        query: ['rest_total_hits_as_int', 'typed_keys']
      }
    }
    return await this.transport.request({ path, method, querystring, body, meta }, options)
  }

  /**
    * Start rollup jobs. If you try to start a job that does not exist, an exception occurs. If you try to start a job that is already started, nothing happens.
    * @see {@link https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-rollup-start-job | Elasticsearch API documentation}
    */
  async startJob (this: That, params: T.RollupStartJobRequest, options?: TransportRequestOptionsWithOutMeta): Promise<T.RollupStartJobResponse>
  async startJob (this: That, params: T.RollupStartJobRequest, options?: TransportRequestOptionsWithMeta): Promise<TransportResult<T.RollupStartJobResponse, unknown>>
  async startJob (this: That, params: T.RollupStartJobRequest, options?: TransportRequestOptions): Promise<T.RollupStartJobResponse>
  async startJob (this: That, params: T.RollupStartJobRequest, options?: TransportRequestOptions): Promise<any> {
    const {
      path: acceptedPath
    } = this[kAcceptedParams]['rollup.start_job']

    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 = 'POST'
    const path = `/_rollup/job/${encodeURIComponent(params.id.toString())}/_start`
    const meta: TransportRequestMetadata = {
      name: 'rollup.start_job',
      pathParts: {
        id: params.id
      },
      acceptedParams: {
        path: ['id'],
        body: [],
        query: []
      }
    }
    return await this.transport.request({ path, method, querystring, body, meta }, options)
  }

  /**
    * Stop rollup jobs. If you try to stop a job that does not exist, an exception occurs. If you try to stop a job that is already stopped, nothing happens. Since only a stopped job can be deleted, it can be useful to block the API until the indexer has fully stopped. This is accomplished with the `wait_for_completion` query parameter, and optionally a timeout. For example: ``` POST _rollup/job/sensor/_stop?wait_for_completion=true&timeout=10s ``` The parameter blocks the API call from returning until either the job has moved to STOPPED or the specified time has elapsed. If the specified time elapses without the job moving to STOPPED, a timeout exception occurs.
    * @see {@link https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-rollup-stop-job | Elasticsearch API documentation}
    */
  async stopJob (this: That, params: T.RollupStopJobRequest, options?: TransportRequestOptionsWithOutMeta): Promise<T.RollupStopJobResponse>
  async stopJob (this: That, params: T.RollupStopJobRequest, options?: TransportRequestOptionsWithMeta): Promise<TransportResult<T.RollupStopJobResponse, unknown>>
  async stopJob (this: That, params: T.RollupStopJobRequest, options?: TransportRequestOptions): Promise<T.RollupStopJobResponse>
  async stopJob (this: That, params: T.RollupStopJobRequest, options?: TransportRequestOptions): Promise<any> {
    const {
      path: acceptedPath
    } = this[kAcceptedParams]['rollup.stop_job']

    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 = 'POST'
    const path = `/_rollup/job/${encodeURIComponent(params.id.toString())}/_stop`
    const meta: TransportRequestMetadata = {
      name: 'rollup.stop_job',
      pathParts: {
        id: params.id
      },
      acceptedParams: {
        path: ['id'],
        body: [],
        query: ['timeout', 'wait_for_completion']
      }
    }
    return await this.transport.request({ path, method, querystring, body, meta }, options)
  }
}
