# pylint: disable=too-many-lines
# coding=utf-8
# --------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# Code generated by Microsoft (R) Python Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is regenerated.
# --------------------------------------------------------------------------
from io import IOBase
import json
import sys
from typing import Any, Callable, Dict, IO, List, Optional, TypeVar, Union, overload

from azure.core.exceptions import (
    ClientAuthenticationError,
    HttpResponseError,
    ResourceExistsError,
    ResourceNotFoundError,
    ResourceNotModifiedError,
    StreamClosedError,
    StreamConsumedError,
    map_error,
)
from azure.core.pipeline import PipelineResponse
from azure.core.rest import HttpRequest, HttpResponse
from azure.core.tracing.decorator import distributed_trace
from azure.core.utils import case_insensitive_dict

from .. import models as _models
from .._model_base import SdkJSONEncoder, _deserialize
from .._serialization import Serializer
from .._validation import api_version_validation
from .._vendor import EventGridConsumerClientMixinABC, EventGridPublisherClientMixinABC

if sys.version_info >= (3, 9):
    from collections.abc import MutableMapping
else:
    from typing import MutableMapping  # type: ignore
T = TypeVar("T")
ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]]
JSON = MutableMapping[str, Any]  # pylint: disable=unsubscriptable-object
_Unset: Any = object()

_SERIALIZER = Serializer()
_SERIALIZER.client_side_validation = False


def build_event_grid_publisher_send_request(topic_name: str, **kwargs: Any) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
    _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

    content_type: str = kwargs.pop("content_type")
    api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2024-06-01"))
    accept = _headers.pop("Accept", "application/json")

    # Construct URL
    _url = "/topics/{topicName}:publish"
    path_format_arguments = {
        "topicName": _SERIALIZER.url("topic_name", topic_name, "str"),
    }

    _url: str = _url.format(**path_format_arguments)  # type: ignore

    # Construct parameters
    _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str")

    # Construct headers
    _headers["content-type"] = _SERIALIZER.header("content_type", content_type, "str")
    _headers["Accept"] = _SERIALIZER.header("accept", accept, "str")

    return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs)


def build_event_grid_publisher_send_events_request(  # pylint: disable=name-too-long
    topic_name: str, **kwargs: Any
) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
    _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

    content_type: str = kwargs.pop("content_type")
    api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2024-06-01"))
    accept = _headers.pop("Accept", "application/json")

    # Construct URL
    _url = "/topics/{topicName}:publish"
    path_format_arguments = {
        "topicName": _SERIALIZER.url("topic_name", topic_name, "str"),
    }

    _url: str = _url.format(**path_format_arguments)  # type: ignore

    # Construct parameters
    _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str")

    # Construct headers
    _headers["content-type"] = _SERIALIZER.header("content_type", content_type, "str")
    _headers["Accept"] = _SERIALIZER.header("accept", accept, "str")

    return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs)


def build_event_grid_consumer_receive_request(  # pylint: disable=name-too-long
    topic_name: str,
    event_subscription_name: str,
    *,
    max_events: Optional[int] = None,
    max_wait_time: Optional[int] = None,
    **kwargs: Any
) -> HttpRequest:
    _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", "2024-06-01"))
    accept = _headers.pop("Accept", "application/json")

    # Construct URL
    _url = "/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:receive"
    path_format_arguments = {
        "topicName": _SERIALIZER.url("topic_name", topic_name, "str"),
        "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, "str"),
    }

    _url: str = _url.format(**path_format_arguments)  # type: ignore

    # Construct parameters
    _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str")
    if max_events is not None:
        _params["maxEvents"] = _SERIALIZER.query("max_events", max_events, "int")
    if max_wait_time is not None:
        _params["maxWaitTime"] = _SERIALIZER.query("max_wait_time", max_wait_time, "int")

    # Construct headers
    _headers["Accept"] = _SERIALIZER.header("accept", accept, "str")

    return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs)


def build_event_grid_consumer_acknowledge_request(  # pylint: disable=name-too-long
    topic_name: str, event_subscription_name: str, **kwargs: Any
) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
    _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

    content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
    api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2024-06-01"))
    accept = _headers.pop("Accept", "application/json")

    # Construct URL
    _url = "/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:acknowledge"
    path_format_arguments = {
        "topicName": _SERIALIZER.url("topic_name", topic_name, "str"),
        "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, "str"),
    }

    _url: str = _url.format(**path_format_arguments)  # type: ignore

    # Construct parameters
    _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str")

    # Construct headers
    if content_type is not None:
        _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str")
    _headers["Accept"] = _SERIALIZER.header("accept", accept, "str")

    return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs)


def build_event_grid_consumer_release_request(  # pylint: disable=name-too-long
    topic_name: str,
    event_subscription_name: str,
    *,
    release_delay_in_seconds: Optional[Union[str, _models.ReleaseDelay]] = None,
    **kwargs: Any
) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
    _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

    content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
    api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2024-06-01"))
    accept = _headers.pop("Accept", "application/json")

    # Construct URL
    _url = "/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:release"
    path_format_arguments = {
        "topicName": _SERIALIZER.url("topic_name", topic_name, "str"),
        "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, "str"),
    }

    _url: str = _url.format(**path_format_arguments)  # type: ignore

    # Construct parameters
    _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str")
    if release_delay_in_seconds is not None:
        _params["releaseDelayInSeconds"] = _SERIALIZER.query(
            "release_delay_in_seconds", release_delay_in_seconds, "str"
        )

    # Construct headers
    if content_type is not None:
        _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str")
    _headers["Accept"] = _SERIALIZER.header("accept", accept, "str")

    return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs)


def build_event_grid_consumer_reject_request(
    topic_name: str, event_subscription_name: str, **kwargs: Any
) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
    _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

    content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
    api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2024-06-01"))
    accept = _headers.pop("Accept", "application/json")

    # Construct URL
    _url = "/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:reject"
    path_format_arguments = {
        "topicName": _SERIALIZER.url("topic_name", topic_name, "str"),
        "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, "str"),
    }

    _url: str = _url.format(**path_format_arguments)  # type: ignore

    # Construct parameters
    _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str")

    # Construct headers
    if content_type is not None:
        _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str")
    _headers["Accept"] = _SERIALIZER.header("accept", accept, "str")

    return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs)


def build_event_grid_consumer_renew_locks_request(  # pylint: disable=name-too-long
    topic_name: str, event_subscription_name: str, **kwargs: Any
) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
    _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

    content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
    api_version: str = kwargs.pop("api_version", _params.pop("api-version", "2024-06-01"))
    accept = _headers.pop("Accept", "application/json")

    # Construct URL
    _url = "/topics/{topicName}/eventsubscriptions/{eventSubscriptionName}:renewLock"
    path_format_arguments = {
        "topicName": _SERIALIZER.url("topic_name", topic_name, "str"),
        "eventSubscriptionName": _SERIALIZER.url("event_subscription_name", event_subscription_name, "str"),
    }

    _url: str = _url.format(**path_format_arguments)  # type: ignore

    # Construct parameters
    _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str")

    # Construct headers
    if content_type is not None:
        _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str")
    _headers["Accept"] = _SERIALIZER.header("accept", accept, "str")

    return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs)


class EventGridPublisherClientOperationsMixin(EventGridPublisherClientMixinABC):

    @distributed_trace
    def _send(self, topic_name: str, event: _models._models.CloudEvent, **kwargs: Any) -> _models._models.PublishResult:
        """Publish a single Cloud Event to a namespace topic.

        :param topic_name: Topic Name. Required.
        :type topic_name: str
        :param event: Single Cloud Event being published. Required.
        :type event: ~azure.eventgrid.models._models.CloudEvent
        :return: PublishResult. The PublishResult is compatible with MutableMapping
        :rtype: ~azure.eventgrid.models._models.PublishResult
        :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 = kwargs.pop("params", {}) or {}

        content_type: str = kwargs.pop(
            "content_type", _headers.pop("content-type", "application/cloudevents+json; charset=utf-8")
        )
        cls: ClsType[_models._models.PublishResult] = kwargs.pop("cls", None)

        _content = json.dumps(event, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_event_grid_publisher_send_request(
            topic_name=topic_name,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(
                _models._models.PublishResult, response.json()  # pylint: disable=protected-access
            )

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

        return deserialized  # type: ignore

    @distributed_trace
    def _send_events(
        self, topic_name: str, events: List[_models._models.CloudEvent], **kwargs: Any
    ) -> _models._models.PublishResult:
        """Publish a batch of Cloud Events to a namespace topic.

        :param topic_name: Topic Name. Required.
        :type topic_name: str
        :param events: Array of Cloud Events being published. Required.
        :type events: list[~azure.eventgrid.models._models.CloudEvent]
        :return: PublishResult. The PublishResult is compatible with MutableMapping
        :rtype: ~azure.eventgrid.models._models.PublishResult
        :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 = kwargs.pop("params", {}) or {}

        content_type: str = kwargs.pop(
            "content_type", _headers.pop("content-type", "application/cloudevents-batch+json; charset=utf-8")
        )
        cls: ClsType[_models._models.PublishResult] = kwargs.pop("cls", None)

        _content = json.dumps(events, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_event_grid_publisher_send_events_request(
            topic_name=topic_name,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(
                _models._models.PublishResult, response.json()  # pylint: disable=protected-access
            )

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

        return deserialized  # type: ignore


class EventGridConsumerClientOperationsMixin(EventGridConsumerClientMixinABC):

    @distributed_trace
    def _receive(
        self,
        topic_name: str,
        event_subscription_name: str,
        *,
        max_events: Optional[int] = None,
        max_wait_time: Optional[int] = None,
        **kwargs: Any
    ) -> _models._models.ReceiveResult:
        """Receive a batch of Cloud Events from a subscription.

        :param topic_name: Topic Name. Required.
        :type topic_name: str
        :param event_subscription_name: Event Subscription Name. Required.
        :type event_subscription_name: str
        :keyword max_events: Max Events count to be received. Minimum value is 1, while maximum value
         is 100 events. If not specified, the default value is 1. Default value is None.
        :paramtype max_events: int
        :keyword max_wait_time: Max wait time value for receive operation in Seconds. It is the time in
         seconds that the server approximately waits for the availability of an event and responds to
         the request. If an event is available, the broker responds immediately to the client. Minimum
         value is 10 seconds, while maximum value is 120 seconds. If not specified, the default value is
         60 seconds. Default value is None.
        :paramtype max_wait_time: int
        :return: ReceiveResult. The ReceiveResult is compatible with MutableMapping
        :rtype: ~azure.eventgrid.models._models.ReceiveResult
        :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 = kwargs.pop("params", {}) or {}

        cls: ClsType[_models._models.ReceiveResult] = kwargs.pop("cls", None)

        _request = build_event_grid_consumer_receive_request(
            topic_name=topic_name,
            event_subscription_name=event_subscription_name,
            max_events=max_events,
            max_wait_time=max_wait_time,
            api_version=self._config.api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(
                _models._models.ReceiveResult, response.json()  # pylint: disable=protected-access
            )

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

        return deserialized  # type: ignore

    @overload
    def _acknowledge(
        self,
        topic_name: str,
        event_subscription_name: str,
        body: JSON,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.AcknowledgeResult: ...
    @overload
    def _acknowledge(
        self,
        topic_name: str,
        event_subscription_name: str,
        *,
        lock_tokens: List[str],
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.AcknowledgeResult: ...
    @overload
    def _acknowledge(
        self,
        topic_name: str,
        event_subscription_name: str,
        body: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.AcknowledgeResult: ...

    @distributed_trace
    def _acknowledge(
        self,
        topic_name: str,
        event_subscription_name: str,
        body: Union[JSON, IO[bytes]] = _Unset,
        *,
        lock_tokens: List[str] = _Unset,
        **kwargs: Any
    ) -> _models.AcknowledgeResult:
        """Acknowledge a batch of Cloud Events. The response will include the set of successfully
        acknowledged lock tokens, along with other failed lock tokens with their corresponding error
        information. Successfully acknowledged events will no longer be available to be received by any
        consumer.

        :param topic_name: Topic Name. Required.
        :type topic_name: str
        :param event_subscription_name: Event Subscription Name. Required.
        :type event_subscription_name: str
        :param body: Is either a JSON type or a IO[bytes] type. Required.
        :type body: JSON or IO[bytes]
        :keyword lock_tokens: Array of lock tokens. Required.
        :paramtype lock_tokens: list[str]
        :return: AcknowledgeResult. The AcknowledgeResult is compatible with MutableMapping
        :rtype: ~azure.eventgrid.models.AcknowledgeResult
        :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 = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.AcknowledgeResult] = kwargs.pop("cls", None)

        if body is _Unset:
            if lock_tokens is _Unset:
                raise TypeError("missing required argument: lock_tokens")
            body = {"lockTokens": lock_tokens}
            body = {k: v for k, v in body.items() if v is not None}
        content_type = content_type or "application/json"
        _content = None
        if isinstance(body, (IOBase, bytes)):
            _content = body
        else:
            _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_event_grid_consumer_acknowledge_request(
            topic_name=topic_name,
            event_subscription_name=event_subscription_name,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.AcknowledgeResult, response.json())

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

        return deserialized  # type: ignore

    @overload
    def _release(
        self,
        topic_name: str,
        event_subscription_name: str,
        body: JSON,
        *,
        release_delay_in_seconds: Optional[Union[str, _models.ReleaseDelay]] = None,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.ReleaseResult: ...
    @overload
    def _release(
        self,
        topic_name: str,
        event_subscription_name: str,
        *,
        lock_tokens: List[str],
        release_delay_in_seconds: Optional[Union[str, _models.ReleaseDelay]] = None,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.ReleaseResult: ...
    @overload
    def _release(
        self,
        topic_name: str,
        event_subscription_name: str,
        body: IO[bytes],
        *,
        release_delay_in_seconds: Optional[Union[str, _models.ReleaseDelay]] = None,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.ReleaseResult: ...

    @distributed_trace
    @api_version_validation(
        params_added_on={"2023-10-01-preview": ["release_delay_in_seconds"]},
    )
    def _release(
        self,
        topic_name: str,
        event_subscription_name: str,
        body: Union[JSON, IO[bytes]] = _Unset,
        *,
        lock_tokens: List[str] = _Unset,
        release_delay_in_seconds: Optional[Union[str, _models.ReleaseDelay]] = None,
        **kwargs: Any
    ) -> _models.ReleaseResult:
        """Release a batch of Cloud Events. The response will include the set of successfully released
        lock tokens, along with other failed lock tokens with their corresponding error information.
        Successfully released events can be received by consumers.

        :param topic_name: Topic Name. Required.
        :type topic_name: str
        :param event_subscription_name: Event Subscription Name. Required.
        :type event_subscription_name: str
        :param body: Is either a JSON type or a IO[bytes] type. Required.
        :type body: JSON or IO[bytes]
        :keyword lock_tokens: Array of lock tokens. Required.
        :paramtype lock_tokens: list[str]
        :keyword release_delay_in_seconds: Release cloud events with the specified delay in seconds.
         Known values are: "0", "10", "60", "600", and "3600". Default value is None.
        :paramtype release_delay_in_seconds: str or ~azure.eventgrid.models.ReleaseDelay
        :return: ReleaseResult. The ReleaseResult is compatible with MutableMapping
        :rtype: ~azure.eventgrid.models.ReleaseResult
        :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 = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.ReleaseResult] = kwargs.pop("cls", None)

        if body is _Unset:
            if lock_tokens is _Unset:
                raise TypeError("missing required argument: lock_tokens")
            body = {"lockTokens": lock_tokens}
            body = {k: v for k, v in body.items() if v is not None}
        content_type = content_type or "application/json"
        _content = None
        if isinstance(body, (IOBase, bytes)):
            _content = body
        else:
            _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_event_grid_consumer_release_request(
            topic_name=topic_name,
            event_subscription_name=event_subscription_name,
            release_delay_in_seconds=release_delay_in_seconds,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.ReleaseResult, response.json())

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

        return deserialized  # type: ignore

    @overload
    def _reject(
        self,
        topic_name: str,
        event_subscription_name: str,
        body: JSON,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.RejectResult: ...
    @overload
    def _reject(
        self,
        topic_name: str,
        event_subscription_name: str,
        *,
        lock_tokens: List[str],
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.RejectResult: ...
    @overload
    def _reject(
        self,
        topic_name: str,
        event_subscription_name: str,
        body: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.RejectResult: ...

    @distributed_trace
    def _reject(
        self,
        topic_name: str,
        event_subscription_name: str,
        body: Union[JSON, IO[bytes]] = _Unset,
        *,
        lock_tokens: List[str] = _Unset,
        **kwargs: Any
    ) -> _models.RejectResult:
        """Reject a batch of Cloud Events. The response will include the set of successfully rejected lock
        tokens, along with other failed lock tokens with their corresponding error information.
        Successfully rejected events will be dead-lettered and can no longer be received by a consumer.

        :param topic_name: Topic Name. Required.
        :type topic_name: str
        :param event_subscription_name: Event Subscription Name. Required.
        :type event_subscription_name: str
        :param body: Is either a JSON type or a IO[bytes] type. Required.
        :type body: JSON or IO[bytes]
        :keyword lock_tokens: Array of lock tokens. Required.
        :paramtype lock_tokens: list[str]
        :return: RejectResult. The RejectResult is compatible with MutableMapping
        :rtype: ~azure.eventgrid.models.RejectResult
        :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 = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.RejectResult] = kwargs.pop("cls", None)

        if body is _Unset:
            if lock_tokens is _Unset:
                raise TypeError("missing required argument: lock_tokens")
            body = {"lockTokens": lock_tokens}
            body = {k: v for k, v in body.items() if v is not None}
        content_type = content_type or "application/json"
        _content = None
        if isinstance(body, (IOBase, bytes)):
            _content = body
        else:
            _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_event_grid_consumer_reject_request(
            topic_name=topic_name,
            event_subscription_name=event_subscription_name,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.RejectResult, response.json())

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

        return deserialized  # type: ignore

    @overload
    def _renew_locks(
        self,
        topic_name: str,
        event_subscription_name: str,
        body: JSON,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.RenewLocksResult: ...
    @overload
    def _renew_locks(
        self,
        topic_name: str,
        event_subscription_name: str,
        *,
        lock_tokens: List[str],
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.RenewLocksResult: ...
    @overload
    def _renew_locks(
        self,
        topic_name: str,
        event_subscription_name: str,
        body: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.RenewLocksResult: ...

    @distributed_trace
    @api_version_validation(
        method_added_on="2023-10-01-preview",
        params_added_on={
            "2023-10-01-preview": ["api_version", "topic_name", "event_subscription_name", "content_type", "accept"]
        },
    )
    def _renew_locks(
        self,
        topic_name: str,
        event_subscription_name: str,
        body: Union[JSON, IO[bytes]] = _Unset,
        *,
        lock_tokens: List[str] = _Unset,
        **kwargs: Any
    ) -> _models.RenewLocksResult:
        """Renew locks for a batch of Cloud Events. The response will include the set of successfully
        renewed lock tokens, along with other failed lock tokens with their corresponding error
        information. Successfully renewed locks will ensure that the associated event is only available
        to the consumer that holds the renewed lock.

        :param topic_name: Topic Name. Required.
        :type topic_name: str
        :param event_subscription_name: Event Subscription Name. Required.
        :type event_subscription_name: str
        :param body: Is either a JSON type or a IO[bytes] type. Required.
        :type body: JSON or IO[bytes]
        :keyword lock_tokens: Array of lock tokens. Required.
        :paramtype lock_tokens: list[str]
        :return: RenewLocksResult. The RenewLocksResult is compatible with MutableMapping
        :rtype: ~azure.eventgrid.models.RenewLocksResult
        :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 = kwargs.pop("params", {}) or {}

        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.RenewLocksResult] = kwargs.pop("cls", None)

        if body is _Unset:
            if lock_tokens is _Unset:
                raise TypeError("missing required argument: lock_tokens")
            body = {"lockTokens": lock_tokens}
            body = {k: v for k, v in body.items() if v is not None}
        content_type = content_type or "application/json"
        _content = None
        if isinstance(body, (IOBase, bytes)):
            _content = body
        else:
            _content = json.dumps(body, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_event_grid_consumer_renew_locks_request(
            topic_name=topic_name,
            event_subscription_name=event_subscription_name,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "endpoint": self._serialize.url("self._config.endpoint", self._config.endpoint, "str", skip_quote=True),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    response.read()  # Load the body in memory and close the socket
                except (StreamConsumedError, StreamClosedError):
                    pass
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response)

        if _stream:
            deserialized = response.iter_bytes()
        else:
            deserialized = _deserialize(_models.RenewLocksResult, response.json())

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

        return deserialized  # type: ignore
