# pylint: disable=line-too-long,useless-suppression,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 collections.abc import MutableMapping
from io import IOBase
import json
from typing import Any, Callable, IO, Optional, TypeVar, Union, overload
import urllib.parse

from azure.core import AsyncPipelineClient
from azure.core.async_paging import AsyncItemPaged, AsyncList
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 AsyncHttpResponse, HttpRequest
from azure.core.tracing.decorator import distributed_trace
from azure.core.tracing.decorator_async import distributed_trace_async
from azure.core.utils import case_insensitive_dict

from ... import models as _models
from ..._operations._operations import (
    build_key_vault_backup_secret_request,
    build_key_vault_delete_secret_request,
    build_key_vault_get_deleted_secret_request,
    build_key_vault_get_deleted_secrets_request,
    build_key_vault_get_secret_request,
    build_key_vault_get_secret_versions_request,
    build_key_vault_get_secrets_request,
    build_key_vault_purge_deleted_secret_request,
    build_key_vault_recover_deleted_secret_request,
    build_key_vault_restore_secret_request,
    build_key_vault_set_secret_request,
    build_key_vault_update_secret_request,
)
from ..._utils.model_base import SdkJSONEncoder, _deserialize, _failsafe_deserialize
from ..._utils.utils import ClientMixinABC
from ..._validation import api_version_validation
from .._configuration import KeyVaultClientConfiguration

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


class _KeyVaultClientOperationsMixin(
    ClientMixinABC[AsyncPipelineClient[HttpRequest, AsyncHttpResponse], KeyVaultClientConfiguration]
):

    @overload
    async def set_secret(
        self,
        secret_name: str,
        parameters: _models.SecretSetParameters,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.SecretBundle:
        """Sets a secret in a specified key vault.

        The SET operation adds a secret to the Azure Key Vault. If the named secret already exists,
        Azure Key Vault creates a new version of that secret. This operation requires the secrets/set
        permission.

        :param secret_name: The name of the secret. The value you provide may be copied globally for
         the purpose of running the service. The value provided should not include personally
         identifiable or sensitive information. Required.
        :type secret_name: str
        :param parameters: The parameters for setting the secret. Required.
        :type parameters: ~azure.keyvault.secrets._generated.models.SecretSetParameters
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: SecretBundle. The SecretBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def set_secret(
        self, secret_name: str, parameters: JSON, *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.SecretBundle:
        """Sets a secret in a specified key vault.

        The SET operation adds a secret to the Azure Key Vault. If the named secret already exists,
        Azure Key Vault creates a new version of that secret. This operation requires the secrets/set
        permission.

        :param secret_name: The name of the secret. The value you provide may be copied globally for
         the purpose of running the service. The value provided should not include personally
         identifiable or sensitive information. Required.
        :type secret_name: str
        :param parameters: The parameters for setting the secret. Required.
        :type parameters: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: SecretBundle. The SecretBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def set_secret(
        self, secret_name: str, parameters: IO[bytes], *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.SecretBundle:
        """Sets a secret in a specified key vault.

        The SET operation adds a secret to the Azure Key Vault. If the named secret already exists,
        Azure Key Vault creates a new version of that secret. This operation requires the secrets/set
        permission.

        :param secret_name: The name of the secret. The value you provide may be copied globally for
         the purpose of running the service. The value provided should not include personally
         identifiable or sensitive information. Required.
        :type secret_name: str
        :param parameters: The parameters for setting the secret. Required.
        :type parameters: IO[bytes]
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: SecretBundle. The SecretBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def set_secret(
        self, secret_name: str, parameters: Union[_models.SecretSetParameters, JSON, IO[bytes]], **kwargs: Any
    ) -> _models.SecretBundle:
        """Sets a secret in a specified key vault.

        The SET operation adds a secret to the Azure Key Vault. If the named secret already exists,
        Azure Key Vault creates a new version of that secret. This operation requires the secrets/set
        permission.

        :param secret_name: The name of the secret. The value you provide may be copied globally for
         the purpose of running the service. The value provided should not include personally
         identifiable or sensitive information. Required.
        :type secret_name: str
        :param parameters: The parameters for setting the secret. Is one of the following types:
         SecretSetParameters, JSON, IO[bytes] Required.
        :type parameters: ~azure.keyvault.secrets._generated.models.SecretSetParameters or JSON or
         IO[bytes]
        :return: SecretBundle. The SecretBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle
        :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.SecretBundle] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

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

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await 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)
            error = _failsafe_deserialize(
                _models.KeyVaultError,
                response,
            )
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes() if _decompress else response.iter_raw()
        else:
            deserialized = _deserialize(_models.SecretBundle, response.json())

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

        return deserialized  # type: ignore

    @distributed_trace_async
    async def delete_secret(self, secret_name: str, **kwargs: Any) -> _models.DeletedSecretBundle:
        """Deletes a secret from a specified key vault.

        The DELETE operation applies to any secret stored in Azure Key Vault. DELETE cannot be applied
        to an individual version of a secret. This operation requires the secrets/delete permission.

        :param secret_name: The name of the secret. Required.
        :type secret_name: str
        :return: DeletedSecretBundle. The DeletedSecretBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.DeletedSecretBundle
        :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.DeletedSecretBundle] = kwargs.pop("cls", None)

        _request = build_key_vault_delete_secret_request(
            secret_name=secret_name,
            api_version=self._config.api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await 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)
            error = _failsafe_deserialize(
                _models.KeyVaultError,
                response,
            )
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes() if _decompress else response.iter_raw()
        else:
            deserialized = _deserialize(_models.DeletedSecretBundle, response.json())

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

        return deserialized  # type: ignore

    @overload
    async def update_secret(
        self,
        secret_name: str,
        secret_version: str,
        parameters: _models.SecretUpdateParameters,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.SecretBundle:
        """Updates the attributes associated with a specified secret in a given key vault.

        The UPDATE operation changes specified attributes of an existing stored secret. Attributes that
        are not specified in the request are left unchanged. The value of a secret itself cannot be
        changed. This operation requires the secrets/set permission.

        :param secret_name: The name of the secret. Required.
        :type secret_name: str
        :param secret_version: The version of the secret. Required.
        :type secret_version: str
        :param parameters: The parameters for update secret operation. Required.
        :type parameters: ~azure.keyvault.secrets._generated.models.SecretUpdateParameters
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: SecretBundle. The SecretBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def update_secret(
        self,
        secret_name: str,
        secret_version: str,
        parameters: JSON,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.SecretBundle:
        """Updates the attributes associated with a specified secret in a given key vault.

        The UPDATE operation changes specified attributes of an existing stored secret. Attributes that
        are not specified in the request are left unchanged. The value of a secret itself cannot be
        changed. This operation requires the secrets/set permission.

        :param secret_name: The name of the secret. Required.
        :type secret_name: str
        :param secret_version: The version of the secret. Required.
        :type secret_version: str
        :param parameters: The parameters for update secret operation. Required.
        :type parameters: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: SecretBundle. The SecretBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def update_secret(
        self,
        secret_name: str,
        secret_version: str,
        parameters: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.SecretBundle:
        """Updates the attributes associated with a specified secret in a given key vault.

        The UPDATE operation changes specified attributes of an existing stored secret. Attributes that
        are not specified in the request are left unchanged. The value of a secret itself cannot be
        changed. This operation requires the secrets/set permission.

        :param secret_name: The name of the secret. Required.
        :type secret_name: str
        :param secret_version: The version of the secret. Required.
        :type secret_version: str
        :param parameters: The parameters for update secret operation. Required.
        :type parameters: IO[bytes]
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: SecretBundle. The SecretBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def update_secret(
        self,
        secret_name: str,
        secret_version: str,
        parameters: Union[_models.SecretUpdateParameters, JSON, IO[bytes]],
        **kwargs: Any
    ) -> _models.SecretBundle:
        """Updates the attributes associated with a specified secret in a given key vault.

        The UPDATE operation changes specified attributes of an existing stored secret. Attributes that
        are not specified in the request are left unchanged. The value of a secret itself cannot be
        changed. This operation requires the secrets/set permission.

        :param secret_name: The name of the secret. Required.
        :type secret_name: str
        :param secret_version: The version of the secret. Required.
        :type secret_version: str
        :param parameters: The parameters for update secret operation. Is one of the following types:
         SecretUpdateParameters, JSON, IO[bytes] Required.
        :type parameters: ~azure.keyvault.secrets._generated.models.SecretUpdateParameters or JSON or
         IO[bytes]
        :return: SecretBundle. The SecretBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle
        :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.SecretBundle] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

        _request = build_key_vault_update_secret_request(
            secret_name=secret_name,
            secret_version=secret_version,
            content_type=content_type,
            api_version=self._config.api_version,
            content=_content,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await 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)
            error = _failsafe_deserialize(
                _models.KeyVaultError,
                response,
            )
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes() if _decompress else response.iter_raw()
        else:
            deserialized = _deserialize(_models.SecretBundle, response.json())

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

        return deserialized  # type: ignore

    @distributed_trace_async
    @api_version_validation(
        params_added_on={"2025-06-01-preview": ["out_content_type"]},
        api_versions_list=["7.5", "7.6-preview.2", "7.6", "2025-06-01-preview", "2025-07-01"],
    )
    async def get_secret(
        self,
        secret_name: str,
        secret_version: str,
        *,
        out_content_type: Optional[Union[str, _models.ContentType]] = None,
        **kwargs: Any
    ) -> _models.SecretBundle:
        """Get a specified secret from a given key vault.

        The GET operation is applicable to any secret stored in Azure Key Vault. This operation
        requires the secrets/get permission.

        :param secret_name: The name of the secret. Required.
        :type secret_name: str
        :param secret_version: The version of the secret. This URI fragment is optional. If not
         specified, the latest version of the secret is returned. Required.
        :type secret_version: str
        :keyword out_content_type: The media type (MIME type) of the certificate. If a supported format
         is specified, the certificate content is converted to the requested format. Currently, only PFX
         to PEM conversion is supported. If an unsupported format is specified, the request is rejected.
         If not specified, the certificate is returned in its original format without conversion. Known
         values are: "application/x-pkcs12" and "application/x-pem-file". Default value is None.
        :paramtype out_content_type: str or ~azure.keyvault.secrets._generated.models.ContentType
        :return: SecretBundle. The SecretBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle
        :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.SecretBundle] = kwargs.pop("cls", None)

        _request = build_key_vault_get_secret_request(
            secret_name=secret_name,
            secret_version=secret_version,
            out_content_type=out_content_type,
            api_version=self._config.api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await 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)
            error = _failsafe_deserialize(
                _models.KeyVaultError,
                response,
            )
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes() if _decompress else response.iter_raw()
        else:
            deserialized = _deserialize(_models.SecretBundle, response.json())

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

        return deserialized  # type: ignore

    @distributed_trace
    def get_secrets(self, *, maxresults: Optional[int] = None, **kwargs: Any) -> AsyncItemPaged["_models.SecretItem"]:
        """List secrets in a specified key vault.

        The Get Secrets operation is applicable to the entire vault. However, only the base secret
        identifier and its attributes are provided in the response. Individual secret versions are not
        listed in the response. This operation requires the secrets/list permission.

        :keyword maxresults: Maximum number of results to return in a page. If not specified the
         service will return up to 25 results. Default value is None.
        :paramtype maxresults: int
        :return: An iterator like instance of SecretItem
        :rtype:
         ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.secrets._generated.models.SecretItem]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = kwargs.pop("params", {}) or {}

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

        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        def prepare_request(next_link=None):
            if not next_link:

                _request = build_key_vault_get_secrets_request(
                    maxresults=maxresults,
                    api_version=self._config.api_version,
                    headers=_headers,
                    params=_params,
                )
                path_format_arguments = {
                    "vaultBaseUrl": self._serialize.url(
                        "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
                    ),
                }
                _request.url = self._client.format_url(_request.url, **path_format_arguments)

            else:
                # make call to next link with the client's api-version
                _parsed_next_link = urllib.parse.urlparse(next_link)
                _next_request_params = case_insensitive_dict(
                    {
                        key: [urllib.parse.quote(v) for v in value]
                        for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items()
                    }
                )
                _next_request_params["api-version"] = self._config.api_version
                _request = HttpRequest(
                    "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
                )
                path_format_arguments = {
                    "vaultBaseUrl": self._serialize.url(
                        "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
                    ),
                }
                _request.url = self._client.format_url(_request.url, **path_format_arguments)

            return _request

        async def extract_data(pipeline_response):
            deserialized = pipeline_response.http_response.json()
            list_of_elem = _deserialize(
                list[_models.SecretItem],
                deserialized.get("value", []),
            )
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.get("nextLink") or None, AsyncList(list_of_elem)

        async def get_next(next_link=None):
            _request = prepare_request(next_link)

            _stream = False
            pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # 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 = _failsafe_deserialize(
                    _models.KeyVaultError,
                    response,
                )
                raise HttpResponseError(response=response, model=error)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)

    @distributed_trace
    def get_secret_versions(
        self, secret_name: str, *, maxresults: Optional[int] = None, **kwargs: Any
    ) -> AsyncItemPaged["_models.SecretItem"]:
        """List all versions of the specified secret.

        The full secret identifier and attributes are provided in the response. No values are returned
        for the secrets. This operations requires the secrets/list permission.

        :param secret_name: The name of the secret. Required.
        :type secret_name: str
        :keyword maxresults: Maximum number of results to return in a page. If not specified the
         service will return up to 25 results. Default value is None.
        :paramtype maxresults: int
        :return: An iterator like instance of SecretItem
        :rtype:
         ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.secrets._generated.models.SecretItem]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = kwargs.pop("params", {}) or {}

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

        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        def prepare_request(next_link=None):
            if not next_link:

                _request = build_key_vault_get_secret_versions_request(
                    secret_name=secret_name,
                    maxresults=maxresults,
                    api_version=self._config.api_version,
                    headers=_headers,
                    params=_params,
                )
                path_format_arguments = {
                    "vaultBaseUrl": self._serialize.url(
                        "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
                    ),
                }
                _request.url = self._client.format_url(_request.url, **path_format_arguments)

            else:
                # make call to next link with the client's api-version
                _parsed_next_link = urllib.parse.urlparse(next_link)
                _next_request_params = case_insensitive_dict(
                    {
                        key: [urllib.parse.quote(v) for v in value]
                        for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items()
                    }
                )
                _next_request_params["api-version"] = self._config.api_version
                _request = HttpRequest(
                    "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
                )
                path_format_arguments = {
                    "vaultBaseUrl": self._serialize.url(
                        "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
                    ),
                }
                _request.url = self._client.format_url(_request.url, **path_format_arguments)

            return _request

        async def extract_data(pipeline_response):
            deserialized = pipeline_response.http_response.json()
            list_of_elem = _deserialize(
                list[_models.SecretItem],
                deserialized.get("value", []),
            )
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.get("nextLink") or None, AsyncList(list_of_elem)

        async def get_next(next_link=None):
            _request = prepare_request(next_link)

            _stream = False
            pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # 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 = _failsafe_deserialize(
                    _models.KeyVaultError,
                    response,
                )
                raise HttpResponseError(response=response, model=error)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)

    @distributed_trace
    def get_deleted_secrets(
        self, *, maxresults: Optional[int] = None, **kwargs: Any
    ) -> AsyncItemPaged["_models.DeletedSecretItem"]:
        """Lists deleted secrets for the specified vault.

        The Get Deleted Secrets operation returns the secrets that have been deleted for a vault
        enabled for soft-delete. This operation requires the secrets/list permission.

        :keyword maxresults: Maximum number of results to return in a page. If not specified the
         service will return up to 25 results. Default value is None.
        :paramtype maxresults: int
        :return: An iterator like instance of DeletedSecretItem
        :rtype:
         ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.secrets._generated.models.DeletedSecretItem]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = kwargs.pop("params", {}) or {}

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

        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

        def prepare_request(next_link=None):
            if not next_link:

                _request = build_key_vault_get_deleted_secrets_request(
                    maxresults=maxresults,
                    api_version=self._config.api_version,
                    headers=_headers,
                    params=_params,
                )
                path_format_arguments = {
                    "vaultBaseUrl": self._serialize.url(
                        "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
                    ),
                }
                _request.url = self._client.format_url(_request.url, **path_format_arguments)

            else:
                # make call to next link with the client's api-version
                _parsed_next_link = urllib.parse.urlparse(next_link)
                _next_request_params = case_insensitive_dict(
                    {
                        key: [urllib.parse.quote(v) for v in value]
                        for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items()
                    }
                )
                _next_request_params["api-version"] = self._config.api_version
                _request = HttpRequest(
                    "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
                )
                path_format_arguments = {
                    "vaultBaseUrl": self._serialize.url(
                        "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
                    ),
                }
                _request.url = self._client.format_url(_request.url, **path_format_arguments)

            return _request

        async def extract_data(pipeline_response):
            deserialized = pipeline_response.http_response.json()
            list_of_elem = _deserialize(
                list[_models.DeletedSecretItem],
                deserialized.get("value", []),
            )
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.get("nextLink") or None, AsyncList(list_of_elem)

        async def get_next(next_link=None):
            _request = prepare_request(next_link)

            _stream = False
            pipeline_response: PipelineResponse = await self._client._pipeline.run(  # type: ignore # 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 = _failsafe_deserialize(
                    _models.KeyVaultError,
                    response,
                )
                raise HttpResponseError(response=response, model=error)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)

    @distributed_trace_async
    async def get_deleted_secret(self, secret_name: str, **kwargs: Any) -> _models.DeletedSecretBundle:
        """Gets the specified deleted secret.

        The Get Deleted Secret operation returns the specified deleted secret along with its
        attributes. This operation requires the secrets/get permission.

        :param secret_name: The name of the secret. Required.
        :type secret_name: str
        :return: DeletedSecretBundle. The DeletedSecretBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.DeletedSecretBundle
        :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.DeletedSecretBundle] = kwargs.pop("cls", None)

        _request = build_key_vault_get_deleted_secret_request(
            secret_name=secret_name,
            api_version=self._config.api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await 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)
            error = _failsafe_deserialize(
                _models.KeyVaultError,
                response,
            )
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes() if _decompress else response.iter_raw()
        else:
            deserialized = _deserialize(_models.DeletedSecretBundle, response.json())

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

        return deserialized  # type: ignore

    @distributed_trace_async
    async def purge_deleted_secret(self, secret_name: str, **kwargs: Any) -> None:
        """Permanently deletes the specified secret.

        The purge deleted secret operation removes the secret permanently, without the possibility of
        recovery. This operation can only be enabled on a soft-delete enabled vault. This operation
        requires the secrets/purge permission.

        :param secret_name: The name of the secret. Required.
        :type secret_name: str
        :return: None
        :rtype: None
        :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[None] = kwargs.pop("cls", None)

        _request = build_key_vault_purge_deleted_secret_request(
            secret_name=secret_name,
            api_version=self._config.api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

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

        response = pipeline_response.http_response

        if response.status_code not in [204]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            error = _failsafe_deserialize(
                _models.KeyVaultError,
                response,
            )
            raise HttpResponseError(response=response, model=error)

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

    @distributed_trace_async
    async def recover_deleted_secret(self, secret_name: str, **kwargs: Any) -> _models.SecretBundle:
        """Recovers the deleted secret to the latest version.

        Recovers the deleted secret in the specified vault. This operation can only be performed on a
        soft-delete enabled vault. This operation requires the secrets/recover permission.

        :param secret_name: The name of the deleted secret. Required.
        :type secret_name: str
        :return: SecretBundle. The SecretBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle
        :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.SecretBundle] = kwargs.pop("cls", None)

        _request = build_key_vault_recover_deleted_secret_request(
            secret_name=secret_name,
            api_version=self._config.api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await 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)
            error = _failsafe_deserialize(
                _models.KeyVaultError,
                response,
            )
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes() if _decompress else response.iter_raw()
        else:
            deserialized = _deserialize(_models.SecretBundle, response.json())

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

        return deserialized  # type: ignore

    @distributed_trace_async
    async def backup_secret(self, secret_name: str, **kwargs: Any) -> _models.BackupSecretResult:
        """Backs up the specified secret.

        Requests that a backup of the specified secret be downloaded to the client. All versions of the
        secret will be downloaded. This operation requires the secrets/backup permission.

        :param secret_name: The name of the secret. Required.
        :type secret_name: str
        :return: BackupSecretResult. The BackupSecretResult is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.BackupSecretResult
        :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.BackupSecretResult] = kwargs.pop("cls", None)

        _request = build_key_vault_backup_secret_request(
            secret_name=secret_name,
            api_version=self._config.api_version,
            headers=_headers,
            params=_params,
        )
        path_format_arguments = {
            "vaultBaseUrl": self._serialize.url(
                "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True
            ),
        }
        _request.url = self._client.format_url(_request.url, **path_format_arguments)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await 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)
            error = _failsafe_deserialize(
                _models.KeyVaultError,
                response,
            )
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes() if _decompress else response.iter_raw()
        else:
            deserialized = _deserialize(_models.BackupSecretResult, response.json())

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

        return deserialized  # type: ignore

    @overload
    async def restore_secret(
        self, parameters: _models.SecretRestoreParameters, *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.SecretBundle:
        """Restores a backed up secret to a vault.

        Restores a backed up secret, and all its versions, to a vault. This operation requires the
        secrets/restore permission.

        :param parameters: The parameters to restore the secret. Required.
        :type parameters: ~azure.keyvault.secrets._generated.models.SecretRestoreParameters
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: SecretBundle. The SecretBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def restore_secret(
        self, parameters: JSON, *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.SecretBundle:
        """Restores a backed up secret to a vault.

        Restores a backed up secret, and all its versions, to a vault. This operation requires the
        secrets/restore permission.

        :param parameters: The parameters to restore the secret. Required.
        :type parameters: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: SecretBundle. The SecretBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def restore_secret(
        self, parameters: IO[bytes], *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.SecretBundle:
        """Restores a backed up secret to a vault.

        Restores a backed up secret, and all its versions, to a vault. This operation requires the
        secrets/restore permission.

        :param parameters: The parameters to restore the secret. Required.
        :type parameters: IO[bytes]
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: SecretBundle. The SecretBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def restore_secret(
        self, parameters: Union[_models.SecretRestoreParameters, JSON, IO[bytes]], **kwargs: Any
    ) -> _models.SecretBundle:
        """Restores a backed up secret to a vault.

        Restores a backed up secret, and all its versions, to a vault. This operation requires the
        secrets/restore permission.

        :param parameters: The parameters to restore the secret. Is one of the following types:
         SecretRestoreParameters, JSON, IO[bytes] Required.
        :type parameters: ~azure.keyvault.secrets._generated.models.SecretRestoreParameters or JSON or
         IO[bytes]
        :return: SecretBundle. The SecretBundle is compatible with MutableMapping
        :rtype: ~azure.keyvault.secrets._generated.models.SecretBundle
        :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.SecretBundle] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True)  # type: ignore

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

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            if _stream:
                try:
                    await 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)
            error = _failsafe_deserialize(
                _models.KeyVaultError,
                response,
            )
            raise HttpResponseError(response=response, model=error)

        if _stream:
            deserialized = response.iter_bytes() if _decompress else response.iter_raw()
        else:
            deserialized = _deserialize(_models.SecretBundle, response.json())

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

        return deserialized  # type: ignore
