# pylint: disable=too-many-lines
# coding=utf-8
# --------------------------------------------------------------------------
# Code generated by Microsoft (R) AutoRest Code Generator (autorest: 3.9.5, generator: @autorest/python@6.39.0)
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------
from collections.abc import MutableMapping
from io import IOBase
from typing import Any, Callable, IO, Optional, TypeVar, Union, overload

from azure.core import AsyncPipelineClient
from azure.core.exceptions import (
    ClientAuthenticationError,
    HttpResponseError,
    ResourceExistsError,
    ResourceNotFoundError,
    ResourceNotModifiedError,
    map_error,
)
from azure.core.pipeline import PipelineResponse
from azure.core.rest import AsyncHttpResponse, HttpRequest
from azure.core.tracing.decorator_async import distributed_trace_async
from azure.core.utils import case_insensitive_dict

from ... import models as _models
from ..._utils.serialization import Deserializer, Serializer
from ...operations._documents_operations import (
    build_autocomplete_get_request,
    build_autocomplete_post_request,
    build_count_request,
    build_get_request,
    build_index_request,
    build_search_get_request,
    build_search_post_request,
    build_suggest_get_request,
    build_suggest_post_request,
)
from .._configuration import SearchIndexClientConfiguration

T = TypeVar("T")
ClsType = Optional[
    Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, dict[str, Any]], Any]
]


class DocumentsOperations:
    """
    .. warning::
        **DO NOT** instantiate this class directly.

        Instead, you should access the following operations through
        :class:`~azure.search.documents.aio.SearchIndexClient`'s
        :attr:`documents` attribute.
    """

    models = _models

    def __init__(self, *args, **kwargs) -> None:
        input_args = list(args)
        self._client: AsyncPipelineClient = (
            input_args.pop(0) if input_args else kwargs.pop("client")
        )
        self._config: SearchIndexClientConfiguration = (
            input_args.pop(0) if input_args else kwargs.pop("config")
        )
        self._serialize: Serializer = (
            input_args.pop(0) if input_args else kwargs.pop("serializer")
        )
        self._deserialize: Deserializer = (
            input_args.pop(0) if input_args else kwargs.pop("deserializer")
        )

    @distributed_trace_async
    async def count(
        self, request_options: Optional[_models.RequestOptions] = None, **kwargs: Any
    ) -> int:
        """Queries the number of documents in the index.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/Count-Documents

        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :return: int or the result of cls(response)
        :rtype: int
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop(
            "api_version", _params.pop("api-version", self._config.api_version)
        )
        cls: ClsType[int] = kwargs.pop("cls", None)

        _x_ms_client_request_id = None
        if request_options is not None:
            _x_ms_client_request_id = request_options.x_ms_client_request_id

        _request = build_count_request(
            x_ms_client_request_id=_x_ms_client_request_id,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "endpoint": self._serialize.url(
                "self._config.endpoint", self._config.endpoint, "str", skip_quote=True
            ),
            "indexName": self._serialize.url(
                "self._config.index_name", self._config.index_name, "str"
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = False
        pipeline_response: PipelineResponse = (
            await self._client._pipeline.run(  # pylint: disable=protected-access
                _request, stream=_stream, **kwargs
            )
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(
                status_code=response.status_code, response=response, error_map=error_map
            )
            error = self._deserialize.failsafe_deserialize(
                _models.ErrorResponse, pipeline_response
            )
            raise HttpResponseError(response=response, model=error)

        deserialized = self._deserialize("int", pipeline_response.http_response)

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @distributed_trace_async
    async def search_get(
        self,
        search_text: Optional[str] = None,
        search_options: Optional[_models.SearchOptions] = None,
        request_options: Optional[_models.RequestOptions] = None,
        **kwargs: Any
    ) -> _models.SearchDocumentsResult:
        """Searches for documents in the index.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/Search-Documents

        :param search_text: A full-text search query expression; Use "*" or omit this parameter to
         match all documents. Default value is None.
        :type search_text: str
        :param search_options: Parameter group. Default value is None.
        :type search_options: ~azure.search.documents.models.SearchOptions
        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :return: SearchDocumentsResult or the result of cls(response)
        :rtype: ~azure.search.documents.models.SearchDocumentsResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop(
            "api_version", _params.pop("api-version", self._config.api_version)
        )
        cls: ClsType[_models.SearchDocumentsResult] = kwargs.pop("cls", None)

        _include_total_result_count = None
        _facets = None
        _filter = None
        _highlight_fields = None
        _highlight_post_tag = None
        _highlight_pre_tag = None
        _minimum_coverage = None
        _order_by = None
        _query_type = None
        _scoring_parameters = None
        _scoring_profile = None
        _search_fields = None
        _search_mode = None
        _scoring_statistics = None
        _session_id = None
        _select = None
        _skip = None
        _top = None
        _x_ms_client_request_id = None
        _semantic_configuration = None
        _semantic_error_handling = None
        _semantic_max_wait_in_milliseconds = None
        _answers = None
        _captions = None
        _semantic_query = None
        _debug = None
        if search_options is not None:
            _answers = search_options.answers
            _captions = search_options.captions
            _debug = search_options.debug
            _facets = search_options.facets
            _filter = search_options.filter
            _highlight_fields = search_options.highlight_fields
            _highlight_post_tag = search_options.highlight_post_tag
            _highlight_pre_tag = search_options.highlight_pre_tag
            _include_total_result_count = search_options.include_total_result_count
            _minimum_coverage = search_options.minimum_coverage
            _order_by = search_options.order_by
            _query_type = search_options.query_type
            _scoring_parameters = search_options.scoring_parameters
            _scoring_profile = search_options.scoring_profile
            _scoring_statistics = search_options.scoring_statistics
            _search_fields = search_options.search_fields
            _search_mode = search_options.search_mode
            _select = search_options.select
            _semantic_configuration = search_options.semantic_configuration
            _semantic_error_handling = search_options.semantic_error_handling
            _semantic_max_wait_in_milliseconds = (
                search_options.semantic_max_wait_in_milliseconds
            )
            _semantic_query = search_options.semantic_query
            _session_id = search_options.session_id
            _skip = search_options.skip
            _top = search_options.top
        if request_options is not None:
            _x_ms_client_request_id = request_options.x_ms_client_request_id

        _request = build_search_get_request(
            search_text=search_text,
            include_total_result_count=_include_total_result_count,
            facets=_facets,
            filter=_filter,
            highlight_fields=_highlight_fields,
            highlight_post_tag=_highlight_post_tag,
            highlight_pre_tag=_highlight_pre_tag,
            minimum_coverage=_minimum_coverage,
            order_by=_order_by,
            query_type=_query_type,
            scoring_parameters=_scoring_parameters,
            scoring_profile=_scoring_profile,
            search_fields=_search_fields,
            search_mode=_search_mode,
            scoring_statistics=_scoring_statistics,
            session_id=_session_id,
            select=_select,
            skip=_skip,
            top=_top,
            x_ms_client_request_id=_x_ms_client_request_id,
            semantic_configuration=_semantic_configuration,
            semantic_error_handling=_semantic_error_handling,
            semantic_max_wait_in_milliseconds=_semantic_max_wait_in_milliseconds,
            answers=_answers,
            captions=_captions,
            semantic_query=_semantic_query,
            debug=_debug,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "endpoint": self._serialize.url(
                "self._config.endpoint", self._config.endpoint, "str", skip_quote=True
            ),
            "indexName": self._serialize.url(
                "self._config.index_name", self._config.index_name, "str"
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = False
        pipeline_response: PipelineResponse = (
            await self._client._pipeline.run(  # pylint: disable=protected-access
                _request, stream=_stream, **kwargs
            )
        )

        response = pipeline_response.http_response

        if response.status_code not in [200, 206]:
            map_error(
                status_code=response.status_code, response=response, error_map=error_map
            )
            error = self._deserialize.failsafe_deserialize(
                _models.ErrorResponse, pipeline_response
            )
            raise HttpResponseError(response=response, model=error)

        deserialized = self._deserialize(
            "SearchDocumentsResult", pipeline_response.http_response
        )

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @overload
    async def search_post(
        self,
        search_request: _models.SearchRequest,
        request_options: Optional[_models.RequestOptions] = None,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.SearchDocumentsResult:
        """Searches for documents in the index.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/Search-Documents

        :param search_request: The definition of the Search request. Required.
        :type search_request: ~azure.search.documents.models.SearchRequest
        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: SearchDocumentsResult or the result of cls(response)
        :rtype: ~azure.search.documents.models.SearchDocumentsResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def search_post(
        self,
        search_request: IO[bytes],
        request_options: Optional[_models.RequestOptions] = None,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.SearchDocumentsResult:
        """Searches for documents in the index.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/Search-Documents

        :param search_request: The definition of the Search request. Required.
        :type search_request: IO[bytes]
        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: SearchDocumentsResult or the result of cls(response)
        :rtype: ~azure.search.documents.models.SearchDocumentsResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def search_post(
        self,
        search_request: Union[_models.SearchRequest, IO[bytes]],
        request_options: Optional[_models.RequestOptions] = None,
        **kwargs: Any
    ) -> _models.SearchDocumentsResult:
        """Searches for documents in the index.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/Search-Documents

        :param search_request: The definition of the Search request. Is either a SearchRequest type or
         a IO[bytes] type. Required.
        :type search_request: ~azure.search.documents.models.SearchRequest or IO[bytes]
        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :return: SearchDocumentsResult or the result of cls(response)
        :rtype: ~azure.search.documents.models.SearchDocumentsResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop(
            "api_version", _params.pop("api-version", self._config.api_version)
        )
        content_type: Optional[str] = kwargs.pop(
            "content_type", _headers.pop("Content-Type", None)
        )
        cls: ClsType[_models.SearchDocumentsResult] = kwargs.pop("cls", None)

        _x_ms_client_request_id = None
        if request_options is not None:
            _x_ms_client_request_id = request_options.x_ms_client_request_id
        content_type = content_type or "application/json"
        _json = None
        _content = None
        if isinstance(search_request, (IOBase, bytes)):
            _content = search_request
        else:
            _json = self._serialize.body(search_request, "SearchRequest")

        _request = build_search_post_request(
            x_ms_client_request_id=_x_ms_client_request_id,
            api_version=api_version,
            content_type=content_type,
            json=_json,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "endpoint": self._serialize.url(
                "self._config.endpoint", self._config.endpoint, "str", skip_quote=True
            ),
            "indexName": self._serialize.url(
                "self._config.index_name", self._config.index_name, "str"
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = False
        pipeline_response: PipelineResponse = (
            await self._client._pipeline.run(  # pylint: disable=protected-access
                _request, stream=_stream, **kwargs
            )
        )

        response = pipeline_response.http_response

        if response.status_code not in [200, 206]:
            map_error(
                status_code=response.status_code, response=response, error_map=error_map
            )
            error = self._deserialize.failsafe_deserialize(
                _models.ErrorResponse, pipeline_response
            )
            raise HttpResponseError(response=response, model=error)

        deserialized = self._deserialize(
            "SearchDocumentsResult", pipeline_response.http_response
        )

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @distributed_trace_async
    async def get(
        self,
        key: str,
        selected_fields: Optional[list[str]] = None,
        request_options: Optional[_models.RequestOptions] = None,
        **kwargs: Any
    ) -> dict[str, Any]:
        """Retrieves a document from the index.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/lookup-document

        :param key: The key of the document to retrieve. Required.
        :type key: str
        :param selected_fields: List of field names to retrieve for the document; Any field not
         retrieved will be missing from the returned document. Default value is None.
        :type selected_fields: list[str]
        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :return: dict mapping str to any or the result of cls(response)
        :rtype: dict[str, any]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop(
            "api_version", _params.pop("api-version", self._config.api_version)
        )
        cls: ClsType[dict[str, Any]] = kwargs.pop("cls", None)

        _x_ms_client_request_id = None
        if request_options is not None:
            _x_ms_client_request_id = request_options.x_ms_client_request_id

        _request = build_get_request(
            key=key,
            selected_fields=selected_fields,
            x_ms_client_request_id=_x_ms_client_request_id,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "endpoint": self._serialize.url(
                "self._config.endpoint", self._config.endpoint, "str", skip_quote=True
            ),
            "indexName": self._serialize.url(
                "self._config.index_name", self._config.index_name, "str"
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = False
        pipeline_response: PipelineResponse = (
            await self._client._pipeline.run(  # pylint: disable=protected-access
                _request, stream=_stream, **kwargs
            )
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(
                status_code=response.status_code, response=response, error_map=error_map
            )
            error = self._deserialize.failsafe_deserialize(
                _models.ErrorResponse, pipeline_response
            )
            raise HttpResponseError(response=response, model=error)

        deserialized = self._deserialize("{object}", pipeline_response.http_response)

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @distributed_trace_async
    async def suggest_get(
        self,
        search_text: str,
        suggester_name: str,
        suggest_options: Optional[_models.SuggestOptions] = None,
        request_options: Optional[_models.RequestOptions] = None,
        **kwargs: Any
    ) -> _models.SuggestDocumentsResult:
        """Suggests documents in the index that match the given partial query text.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/suggestions

        :param search_text: The search text to use to suggest documents. Must be at least 1 character,
         and no more than 100 characters. Required.
        :type search_text: str
        :param suggester_name: The name of the suggester as specified in the suggesters collection
         that's part of the index definition. Required.
        :type suggester_name: str
        :param suggest_options: Parameter group. Default value is None.
        :type suggest_options: ~azure.search.documents.models.SuggestOptions
        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :return: SuggestDocumentsResult or the result of cls(response)
        :rtype: ~azure.search.documents.models.SuggestDocumentsResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop(
            "api_version", _params.pop("api-version", self._config.api_version)
        )
        cls: ClsType[_models.SuggestDocumentsResult] = kwargs.pop("cls", None)

        _filter = None
        _use_fuzzy_matching = None
        _highlight_post_tag = None
        _highlight_pre_tag = None
        _minimum_coverage = None
        _order_by = None
        _search_fields = None
        _select = None
        _top = None
        _x_ms_client_request_id = None
        if suggest_options is not None:
            _filter = suggest_options.filter
            _highlight_post_tag = suggest_options.highlight_post_tag
            _highlight_pre_tag = suggest_options.highlight_pre_tag
            _minimum_coverage = suggest_options.minimum_coverage
            _order_by = suggest_options.order_by
            _search_fields = suggest_options.search_fields
            _select = suggest_options.select
            _top = suggest_options.top
            _use_fuzzy_matching = suggest_options.use_fuzzy_matching
        if request_options is not None:
            _x_ms_client_request_id = request_options.x_ms_client_request_id

        _request = build_suggest_get_request(
            search_text=search_text,
            suggester_name=suggester_name,
            filter=_filter,
            use_fuzzy_matching=_use_fuzzy_matching,
            highlight_post_tag=_highlight_post_tag,
            highlight_pre_tag=_highlight_pre_tag,
            minimum_coverage=_minimum_coverage,
            order_by=_order_by,
            search_fields=_search_fields,
            select=_select,
            top=_top,
            x_ms_client_request_id=_x_ms_client_request_id,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "endpoint": self._serialize.url(
                "self._config.endpoint", self._config.endpoint, "str", skip_quote=True
            ),
            "indexName": self._serialize.url(
                "self._config.index_name", self._config.index_name, "str"
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = False
        pipeline_response: PipelineResponse = (
            await self._client._pipeline.run(  # pylint: disable=protected-access
                _request, stream=_stream, **kwargs
            )
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(
                status_code=response.status_code, response=response, error_map=error_map
            )
            error = self._deserialize.failsafe_deserialize(
                _models.ErrorResponse, pipeline_response
            )
            raise HttpResponseError(response=response, model=error)

        deserialized = self._deserialize(
            "SuggestDocumentsResult", pipeline_response.http_response
        )

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @overload
    async def suggest_post(
        self,
        suggest_request: _models.SuggestRequest,
        request_options: Optional[_models.RequestOptions] = None,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.SuggestDocumentsResult:
        """Suggests documents in the index that match the given partial query text.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/suggestions

        :param suggest_request: The Suggest request. Required.
        :type suggest_request: ~azure.search.documents.models.SuggestRequest
        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: SuggestDocumentsResult or the result of cls(response)
        :rtype: ~azure.search.documents.models.SuggestDocumentsResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def suggest_post(
        self,
        suggest_request: IO[bytes],
        request_options: Optional[_models.RequestOptions] = None,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.SuggestDocumentsResult:
        """Suggests documents in the index that match the given partial query text.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/suggestions

        :param suggest_request: The Suggest request. Required.
        :type suggest_request: IO[bytes]
        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: SuggestDocumentsResult or the result of cls(response)
        :rtype: ~azure.search.documents.models.SuggestDocumentsResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def suggest_post(
        self,
        suggest_request: Union[_models.SuggestRequest, IO[bytes]],
        request_options: Optional[_models.RequestOptions] = None,
        **kwargs: Any
    ) -> _models.SuggestDocumentsResult:
        """Suggests documents in the index that match the given partial query text.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/suggestions

        :param suggest_request: The Suggest request. Is either a SuggestRequest type or a IO[bytes]
         type. Required.
        :type suggest_request: ~azure.search.documents.models.SuggestRequest or IO[bytes]
        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :return: SuggestDocumentsResult or the result of cls(response)
        :rtype: ~azure.search.documents.models.SuggestDocumentsResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop(
            "api_version", _params.pop("api-version", self._config.api_version)
        )
        content_type: Optional[str] = kwargs.pop(
            "content_type", _headers.pop("Content-Type", None)
        )
        cls: ClsType[_models.SuggestDocumentsResult] = kwargs.pop("cls", None)

        _x_ms_client_request_id = None
        if request_options is not None:
            _x_ms_client_request_id = request_options.x_ms_client_request_id
        content_type = content_type or "application/json"
        _json = None
        _content = None
        if isinstance(suggest_request, (IOBase, bytes)):
            _content = suggest_request
        else:
            _json = self._serialize.body(suggest_request, "SuggestRequest")

        _request = build_suggest_post_request(
            x_ms_client_request_id=_x_ms_client_request_id,
            api_version=api_version,
            content_type=content_type,
            json=_json,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "endpoint": self._serialize.url(
                "self._config.endpoint", self._config.endpoint, "str", skip_quote=True
            ),
            "indexName": self._serialize.url(
                "self._config.index_name", self._config.index_name, "str"
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = False
        pipeline_response: PipelineResponse = (
            await self._client._pipeline.run(  # pylint: disable=protected-access
                _request, stream=_stream, **kwargs
            )
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(
                status_code=response.status_code, response=response, error_map=error_map
            )
            error = self._deserialize.failsafe_deserialize(
                _models.ErrorResponse, pipeline_response
            )
            raise HttpResponseError(response=response, model=error)

        deserialized = self._deserialize(
            "SuggestDocumentsResult", pipeline_response.http_response
        )

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @overload
    async def index(
        self,
        batch: _models.IndexBatch,
        request_options: Optional[_models.RequestOptions] = None,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.IndexDocumentsResult:
        """Sends a batch of document write actions to the index.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/addupdate-or-delete-documents

        :param batch: The batch of index actions. Required.
        :type batch: ~azure.search.documents.models.IndexBatch
        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: IndexDocumentsResult or the result of cls(response)
        :rtype: ~azure.search.documents.models.IndexDocumentsResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def index(
        self,
        batch: IO[bytes],
        request_options: Optional[_models.RequestOptions] = None,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.IndexDocumentsResult:
        """Sends a batch of document write actions to the index.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/addupdate-or-delete-documents

        :param batch: The batch of index actions. Required.
        :type batch: IO[bytes]
        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: IndexDocumentsResult or the result of cls(response)
        :rtype: ~azure.search.documents.models.IndexDocumentsResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def index(
        self,
        batch: Union[_models.IndexBatch, IO[bytes]],
        request_options: Optional[_models.RequestOptions] = None,
        **kwargs: Any
    ) -> _models.IndexDocumentsResult:
        """Sends a batch of document write actions to the index.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/addupdate-or-delete-documents

        :param batch: The batch of index actions. Is either a IndexBatch type or a IO[bytes] type.
         Required.
        :type batch: ~azure.search.documents.models.IndexBatch or IO[bytes]
        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :return: IndexDocumentsResult or the result of cls(response)
        :rtype: ~azure.search.documents.models.IndexDocumentsResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop(
            "api_version", _params.pop("api-version", self._config.api_version)
        )
        content_type: Optional[str] = kwargs.pop(
            "content_type", _headers.pop("Content-Type", None)
        )
        cls: ClsType[_models.IndexDocumentsResult] = kwargs.pop("cls", None)

        _x_ms_client_request_id = None
        if request_options is not None:
            _x_ms_client_request_id = request_options.x_ms_client_request_id
        content_type = content_type or "application/json"
        _json = None
        _content = None
        if isinstance(batch, (IOBase, bytes)):
            _content = batch
        else:
            _json = self._serialize.body(batch, "IndexBatch")

        _request = build_index_request(
            x_ms_client_request_id=_x_ms_client_request_id,
            api_version=api_version,
            content_type=content_type,
            json=_json,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "endpoint": self._serialize.url(
                "self._config.endpoint", self._config.endpoint, "str", skip_quote=True
            ),
            "indexName": self._serialize.url(
                "self._config.index_name", self._config.index_name, "str"
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = False
        pipeline_response: PipelineResponse = (
            await self._client._pipeline.run(  # pylint: disable=protected-access
                _request, stream=_stream, **kwargs
            )
        )

        response = pipeline_response.http_response

        if response.status_code not in [200, 207]:
            map_error(
                status_code=response.status_code, response=response, error_map=error_map
            )
            error = self._deserialize.failsafe_deserialize(
                _models.ErrorResponse, pipeline_response
            )
            raise HttpResponseError(response=response, model=error)

        deserialized = self._deserialize(
            "IndexDocumentsResult", pipeline_response.http_response
        )

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @distributed_trace_async
    async def autocomplete_get(
        self,
        search_text: str,
        suggester_name: str,
        request_options: Optional[_models.RequestOptions] = None,
        autocomplete_options: Optional[_models.AutocompleteOptions] = None,
        **kwargs: Any
    ) -> _models.AutocompleteResult:
        """Autocompletes incomplete query terms based on input text and matching terms in the index.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/autocomplete

        :param search_text: The incomplete term which should be auto-completed. Required.
        :type search_text: str
        :param suggester_name: The name of the suggester as specified in the suggesters collection
         that's part of the index definition. Required.
        :type suggester_name: str
        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :param autocomplete_options: Parameter group. Default value is None.
        :type autocomplete_options: ~azure.search.documents.models.AutocompleteOptions
        :return: AutocompleteResult or the result of cls(response)
        :rtype: ~azure.search.documents.models.AutocompleteResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop(
            "api_version", _params.pop("api-version", self._config.api_version)
        )
        cls: ClsType[_models.AutocompleteResult] = kwargs.pop("cls", None)

        _x_ms_client_request_id = None
        _autocomplete_mode = None
        _filter = None
        _use_fuzzy_matching = None
        _highlight_post_tag = None
        _highlight_pre_tag = None
        _minimum_coverage = None
        _search_fields = None
        _top = None
        if request_options is not None:
            _x_ms_client_request_id = request_options.x_ms_client_request_id
        if autocomplete_options is not None:
            _autocomplete_mode = autocomplete_options.autocomplete_mode
            _filter = autocomplete_options.filter
            _highlight_post_tag = autocomplete_options.highlight_post_tag
            _highlight_pre_tag = autocomplete_options.highlight_pre_tag
            _minimum_coverage = autocomplete_options.minimum_coverage
            _search_fields = autocomplete_options.search_fields
            _top = autocomplete_options.top
            _use_fuzzy_matching = autocomplete_options.use_fuzzy_matching

        _request = build_autocomplete_get_request(
            search_text=search_text,
            suggester_name=suggester_name,
            x_ms_client_request_id=_x_ms_client_request_id,
            autocomplete_mode=_autocomplete_mode,
            filter=_filter,
            use_fuzzy_matching=_use_fuzzy_matching,
            highlight_post_tag=_highlight_post_tag,
            highlight_pre_tag=_highlight_pre_tag,
            minimum_coverage=_minimum_coverage,
            search_fields=_search_fields,
            top=_top,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "endpoint": self._serialize.url(
                "self._config.endpoint", self._config.endpoint, "str", skip_quote=True
            ),
            "indexName": self._serialize.url(
                "self._config.index_name", self._config.index_name, "str"
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = False
        pipeline_response: PipelineResponse = (
            await self._client._pipeline.run(  # pylint: disable=protected-access
                _request, stream=_stream, **kwargs
            )
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(
                status_code=response.status_code, response=response, error_map=error_map
            )
            error = self._deserialize.failsafe_deserialize(
                _models.ErrorResponse, pipeline_response
            )
            raise HttpResponseError(response=response, model=error)

        deserialized = self._deserialize(
            "AutocompleteResult", pipeline_response.http_response
        )

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore

    @overload
    async def autocomplete_post(
        self,
        autocomplete_request: _models.AutocompleteRequest,
        request_options: Optional[_models.RequestOptions] = None,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.AutocompleteResult:
        """Autocompletes incomplete query terms based on input text and matching terms in the index.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/autocomplete

        :param autocomplete_request: The definition of the Autocomplete request. Required.
        :type autocomplete_request: ~azure.search.documents.models.AutocompleteRequest
        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: AutocompleteResult or the result of cls(response)
        :rtype: ~azure.search.documents.models.AutocompleteResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def autocomplete_post(
        self,
        autocomplete_request: IO[bytes],
        request_options: Optional[_models.RequestOptions] = None,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.AutocompleteResult:
        """Autocompletes incomplete query terms based on input text and matching terms in the index.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/autocomplete

        :param autocomplete_request: The definition of the Autocomplete request. Required.
        :type autocomplete_request: IO[bytes]
        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: AutocompleteResult or the result of cls(response)
        :rtype: ~azure.search.documents.models.AutocompleteResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def autocomplete_post(
        self,
        autocomplete_request: Union[_models.AutocompleteRequest, IO[bytes]],
        request_options: Optional[_models.RequestOptions] = None,
        **kwargs: Any
    ) -> _models.AutocompleteResult:
        """Autocompletes incomplete query terms based on input text and matching terms in the index.

        .. seealso::
           - https://learn.microsoft.com/rest/api/searchservice/autocomplete

        :param autocomplete_request: The definition of the Autocomplete request. Is either a
         AutocompleteRequest type or a IO[bytes] type. Required.
        :type autocomplete_request: ~azure.search.documents.models.AutocompleteRequest or IO[bytes]
        :param request_options: Parameter group. Default value is None.
        :type request_options: ~azure.search.documents.models.RequestOptions
        :return: AutocompleteResult or the result of cls(response)
        :rtype: ~azure.search.documents.models.AutocompleteResult
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop(
            "api_version", _params.pop("api-version", self._config.api_version)
        )
        content_type: Optional[str] = kwargs.pop(
            "content_type", _headers.pop("Content-Type", None)
        )
        cls: ClsType[_models.AutocompleteResult] = kwargs.pop("cls", None)

        _x_ms_client_request_id = None
        if request_options is not None:
            _x_ms_client_request_id = request_options.x_ms_client_request_id
        content_type = content_type or "application/json"
        _json = None
        _content = None
        if isinstance(autocomplete_request, (IOBase, bytes)):
            _content = autocomplete_request
        else:
            _json = self._serialize.body(autocomplete_request, "AutocompleteRequest")

        _request = build_autocomplete_post_request(
            x_ms_client_request_id=_x_ms_client_request_id,
            api_version=api_version,
            content_type=content_type,
            json=_json,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "endpoint": self._serialize.url(
                "self._config.endpoint", self._config.endpoint, "str", skip_quote=True
            ),
            "indexName": self._serialize.url(
                "self._config.index_name", self._config.index_name, "str"
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

        _stream = False
        pipeline_response: PipelineResponse = (
            await self._client._pipeline.run(  # pylint: disable=protected-access
                _request, stream=_stream, **kwargs
            )
        )

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(
                status_code=response.status_code, response=response, error_map=error_map
            )
            error = self._deserialize.failsafe_deserialize(
                _models.ErrorResponse, pipeline_response
            )
            raise HttpResponseError(response=response, model=error)

        deserialized = self._deserialize(
            "AutocompleteResult", pipeline_response.http_response
        )

        if cls:
            return cls(pipeline_response, deserialized, {})  # type: ignore

        return deserialized  # type: ignore
