# 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) AutoRest 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
from typing import Any, Callable, Dict, 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,
    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 azure.mgmt.core.exceptions import ARMErrorFormat

from ... import models as _models
from ..._utils.serialization import Deserializer, Serializer
from ...operations._operations import (
    build_policy_assignments_create_by_id_request,
    build_policy_assignments_create_request,
    build_policy_assignments_delete_by_id_request,
    build_policy_assignments_delete_request,
    build_policy_assignments_get_by_id_request,
    build_policy_assignments_get_request,
    build_policy_assignments_list_for_management_group_request,
    build_policy_assignments_list_for_resource_group_request,
    build_policy_assignments_list_for_resource_request,
    build_policy_assignments_list_request,
    build_policy_definitions_create_or_update_at_management_group_request,
    build_policy_definitions_create_or_update_request,
    build_policy_definitions_delete_at_management_group_request,
    build_policy_definitions_delete_request,
    build_policy_definitions_get_at_management_group_request,
    build_policy_definitions_get_built_in_request,
    build_policy_definitions_get_request,
    build_policy_definitions_list_built_in_request,
    build_policy_definitions_list_by_management_group_request,
    build_policy_definitions_list_request,
    build_policy_set_definitions_create_or_update_at_management_group_request,
    build_policy_set_definitions_create_or_update_request,
    build_policy_set_definitions_delete_at_management_group_request,
    build_policy_set_definitions_delete_request,
    build_policy_set_definitions_get_at_management_group_request,
    build_policy_set_definitions_get_built_in_request,
    build_policy_set_definitions_get_request,
    build_policy_set_definitions_list_built_in_request,
    build_policy_set_definitions_list_by_management_group_request,
    build_policy_set_definitions_list_request,
)
from .._configuration import PolicyClientConfiguration

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


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

        Instead, you should access the following operations through
        :class:`~azure.mgmt.resource.policy.v2019_09_01.aio.PolicyClient`'s
        :attr:`policy_assignments` attribute.
    """

    models = _models

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

    @distributed_trace_async
    async def delete(
        self, scope: str, policy_assignment_name: str, **kwargs: Any
    ) -> Optional[_models.PolicyAssignment]:
        """Deletes a policy assignment.

        This operation deletes a policy assignment, given its name and the scope it was created in. The
        scope of a policy assignment is the part of its ID preceding
        '/providers/Microsoft.Authorization/policyAssignments/{policyAssignmentName}'.

        :param scope: The scope of the policy assignment. Valid scopes are: management group (format:
         '/providers/Microsoft.Management/managementGroups/{managementGroup}'), subscription (format:
         '/subscriptions/{subscriptionId}'), resource group (format:
         '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}', or resource (format:
         '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/[{parentResourcePath}/]{resourceType}/{resourceName}'.
         Required.
        :type scope: str
        :param policy_assignment_name: The name of the policy assignment to delete. Required.
        :type policy_assignment_name: str
        :return: PolicyAssignment or None or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment or 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 = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[Optional[_models.PolicyAssignment]] = kwargs.pop("cls", None)

        _request = build_policy_assignments_delete_request(
            scope=scope,
            policy_assignment_name=policy_assignment_name,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [200, 204]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

        deserialized = None
        if response.status_code == 200:
            deserialized = self._deserialize("PolicyAssignment", pipeline_response.http_response)

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

        return deserialized  # type: ignore

    @overload
    async def create(
        self,
        scope: str,
        policy_assignment_name: str,
        parameters: _models.PolicyAssignment,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.PolicyAssignment:
        """Creates or updates a policy assignment.

        This operation creates or updates a policy assignment with the given scope and name. Policy
        assignments apply to all resources contained within their scope. For example, when you assign a
        policy at resource group scope, that policy applies to all resources in the group.

        :param scope: The scope of the policy assignment. Valid scopes are: management group (format:
         '/providers/Microsoft.Management/managementGroups/{managementGroup}'), subscription (format:
         '/subscriptions/{subscriptionId}'), resource group (format:
         '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}', or resource (format:
         '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/[{parentResourcePath}/]{resourceType}/{resourceName}'.
         Required.
        :type scope: str
        :param policy_assignment_name: The name of the policy assignment. Required.
        :type policy_assignment_name: str
        :param parameters: Parameters for the policy assignment. Required.
        :type parameters: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: PolicyAssignment or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def create(
        self,
        scope: str,
        policy_assignment_name: str,
        parameters: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.PolicyAssignment:
        """Creates or updates a policy assignment.

        This operation creates or updates a policy assignment with the given scope and name. Policy
        assignments apply to all resources contained within their scope. For example, when you assign a
        policy at resource group scope, that policy applies to all resources in the group.

        :param scope: The scope of the policy assignment. Valid scopes are: management group (format:
         '/providers/Microsoft.Management/managementGroups/{managementGroup}'), subscription (format:
         '/subscriptions/{subscriptionId}'), resource group (format:
         '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}', or resource (format:
         '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/[{parentResourcePath}/]{resourceType}/{resourceName}'.
         Required.
        :type scope: str
        :param policy_assignment_name: The name of the policy assignment. Required.
        :type policy_assignment_name: str
        :param parameters: Parameters for the policy assignment. 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: PolicyAssignment or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def create(
        self,
        scope: str,
        policy_assignment_name: str,
        parameters: Union[_models.PolicyAssignment, IO[bytes]],
        **kwargs: Any
    ) -> _models.PolicyAssignment:
        """Creates or updates a policy assignment.

        This operation creates or updates a policy assignment with the given scope and name. Policy
        assignments apply to all resources contained within their scope. For example, when you assign a
        policy at resource group scope, that policy applies to all resources in the group.

        :param scope: The scope of the policy assignment. Valid scopes are: management group (format:
         '/providers/Microsoft.Management/managementGroups/{managementGroup}'), subscription (format:
         '/subscriptions/{subscriptionId}'), resource group (format:
         '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}', or resource (format:
         '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/[{parentResourcePath}/]{resourceType}/{resourceName}'.
         Required.
        :type scope: str
        :param policy_assignment_name: The name of the policy assignment. Required.
        :type policy_assignment_name: str
        :param parameters: Parameters for the policy assignment. Is either a PolicyAssignment type or a
         IO[bytes] type. Required.
        :type parameters: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment or IO[bytes]
        :return: PolicyAssignment or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.PolicyAssignment] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _json = None
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _json = self._serialize.body(parameters, "PolicyAssignment")

        _request = build_policy_assignments_create_request(
            scope=scope,
            policy_assignment_name=policy_assignment_name,
            api_version=api_version,
            content_type=content_type,
            json=_json,
            content=_content,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [201]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

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

        return deserialized  # type: ignore

    @distributed_trace_async
    async def get(self, scope: str, policy_assignment_name: str, **kwargs: Any) -> _models.PolicyAssignment:
        """Retrieves a policy assignment.

        This operation retrieves a single policy assignment, given its name and the scope it was
        created at.

        :param scope: The scope of the policy assignment. Valid scopes are: management group (format:
         '/providers/Microsoft.Management/managementGroups/{managementGroup}'), subscription (format:
         '/subscriptions/{subscriptionId}'), resource group (format:
         '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}', or resource (format:
         '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/[{parentResourcePath}/]{resourceType}/{resourceName}'.
         Required.
        :type scope: str
        :param policy_assignment_name: The name of the policy assignment to get. Required.
        :type policy_assignment_name: str
        :return: PolicyAssignment or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicyAssignment] = kwargs.pop("cls", None)

        _request = build_policy_assignments_get_request(
            scope=scope,
            policy_assignment_name=policy_assignment_name,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

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

        return deserialized  # type: ignore

    @distributed_trace
    def list_for_resource_group(
        self, resource_group_name: str, filter: Optional[str] = None, **kwargs: Any
    ) -> AsyncItemPaged["_models.PolicyAssignment"]:
        """Retrieves all policy assignments that apply to a resource group.

        This operation retrieves the list of all policy assignments associated with the given resource
        group in the given subscription that match the optional given $filter. Valid values for $filter
        are: 'atScope()' or 'policyDefinitionId eq '{value}''. If $filter is not provided, the
        unfiltered list includes all policy assignments associated with the resource group, including
        those that apply directly or apply from containing scopes, as well as any applied to resources
        contained within the resource group. If $filter=atScope() is provided, the returned list
        includes all policy assignments that apply to the resource group, which is everything in the
        unfiltered list except those applied to resources contained within the resource group. If
        $filter=policyDefinitionId eq '{value}' is provided, the returned list includes all policy
        assignments of the policy definition whose id is {value} that apply to the resource group.

        :param resource_group_name: The name of the resource group that contains policy assignments.
         Required.
        :type resource_group_name: str
        :param filter: The filter to apply on the operation. Valid values for $filter are: 'atScope()'
         or 'policyDefinitionId eq '{value}''. If $filter is not provided, no filtering is performed.
         Default value is None.
        :type filter: str
        :return: An iterator like instance of either PolicyAssignment or the result of cls(response)
        :rtype:
         ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicyAssignmentListResult] = 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_policy_assignments_list_for_resource_group_request(
                    resource_group_name=resource_group_name,
                    subscription_id=self._config.subscription_id,
                    filter=filter,
                    api_version=api_version,
                    headers=_headers,
                    params=_params,
                )
                _request.url = self._client.format_url(_request.url)

            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._api_version
                _request = HttpRequest(
                    "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
                )
                _request.url = self._client.format_url(_request.url)
                _request.method = "GET"
            return _request

        async def extract_data(pipeline_response):
            deserialized = self._deserialize("PolicyAssignmentListResult", pipeline_response)
            list_of_elem = deserialized.value
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.next_link 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(  # 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)
                raise HttpResponseError(response=response, error_format=ARMErrorFormat)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)

    @distributed_trace
    def list_for_resource(
        self,
        resource_group_name: str,
        resource_provider_namespace: str,
        parent_resource_path: str,
        resource_type: str,
        resource_name: str,
        filter: Optional[str] = None,
        **kwargs: Any
    ) -> AsyncItemPaged["_models.PolicyAssignment"]:
        """Retrieves all policy assignments that apply to a resource.

        This operation retrieves the list of all policy assignments associated with the specified
        resource in the given resource group and subscription that match the optional given $filter.
        Valid values for $filter are: 'atScope()' or 'policyDefinitionId eq '{value}''. If $filter is
        not provided, the unfiltered list includes all policy assignments associated with the resource,
        including those that apply directly or from all containing scopes, as well as any applied to
        resources contained within the resource. If $filter=atScope() is provided, the returned list
        includes all policy assignments that apply to the resource, which is everything in the
        unfiltered list except those applied to resources contained within the resource. If
        $filter=policyDefinitionId eq '{value}' is provided, the returned list includes all policy
        assignments of the policy definition whose id is {value} that apply to the resource. Three
        parameters plus the resource name are used to identify a specific resource. If the resource is
        not part of a parent resource (the more common case), the parent resource path should not be
        provided (or provided as ''). For example a web app could be specified as
        ({resourceProviderNamespace} == 'Microsoft.Web', {parentResourcePath} == '', {resourceType} ==
        'sites', {resourceName} == 'MyWebApp'). If the resource is part of a parent resource, then all
        parameters should be provided. For example a virtual machine DNS name could be specified as
        ({resourceProviderNamespace} == 'Microsoft.Compute', {parentResourcePath} ==
        'virtualMachines/MyVirtualMachine', {resourceType} == 'domainNames', {resourceName} ==
        'MyComputerName'). A convenient alternative to providing the namespace and type name separately
        is to provide both in the {resourceType} parameter, format: ({resourceProviderNamespace} == '',
        {parentResourcePath} == '', {resourceType} == 'Microsoft.Web/sites', {resourceName} ==
        'MyWebApp').

        :param resource_group_name: The name of the resource group containing the resource. Required.
        :type resource_group_name: str
        :param resource_provider_namespace: The namespace of the resource provider. For example, the
         namespace of a virtual machine is Microsoft.Compute (from Microsoft.Compute/virtualMachines).
         Required.
        :type resource_provider_namespace: str
        :param parent_resource_path: The parent resource path. Use empty string if there is none.
         Required.
        :type parent_resource_path: str
        :param resource_type: The resource type name. For example the type name of a web app is 'sites'
         (from Microsoft.Web/sites). Required.
        :type resource_type: str
        :param resource_name: The name of the resource. Required.
        :type resource_name: str
        :param filter: The filter to apply on the operation. Valid values for $filter are: 'atScope()'
         or 'policyDefinitionId eq '{value}''. If $filter is not provided, no filtering is performed.
         Default value is None.
        :type filter: str
        :return: An iterator like instance of either PolicyAssignment or the result of cls(response)
        :rtype:
         ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicyAssignmentListResult] = 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_policy_assignments_list_for_resource_request(
                    resource_group_name=resource_group_name,
                    resource_provider_namespace=resource_provider_namespace,
                    parent_resource_path=parent_resource_path,
                    resource_type=resource_type,
                    resource_name=resource_name,
                    subscription_id=self._config.subscription_id,
                    filter=filter,
                    api_version=api_version,
                    headers=_headers,
                    params=_params,
                )
                _request.url = self._client.format_url(_request.url)

            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._api_version
                _request = HttpRequest(
                    "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
                )
                _request.url = self._client.format_url(_request.url)
                _request.method = "GET"
            return _request

        async def extract_data(pipeline_response):
            deserialized = self._deserialize("PolicyAssignmentListResult", pipeline_response)
            list_of_elem = deserialized.value
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.next_link 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(  # 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)
                raise HttpResponseError(response=response, error_format=ARMErrorFormat)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)

    @distributed_trace
    def list_for_management_group(
        self, management_group_id: str, filter: str, **kwargs: Any
    ) -> AsyncItemPaged["_models.PolicyAssignment"]:
        """Retrieves all policy assignments that apply to a management group.

        This operation retrieves the list of all policy assignments applicable to the management group
        that match the given $filter. Valid values for $filter are: 'atScope()' or 'policyDefinitionId
        eq '{value}''. If $filter=atScope() is provided, the returned list includes all policy
        assignments that are assigned to the management group or the management group's ancestors. If
        $filter=policyDefinitionId eq '{value}' is provided, the returned list includes all policy
        assignments of the policy definition whose id is {value} that apply to the management group.

        :param management_group_id: The ID of the management group. Required.
        :type management_group_id: str
        :param filter: The filter to apply on the operation. Valid values for $filter are: 'atScope()'
         or 'policyDefinitionId eq '{value}''. A filter is required when listing policy assignments at
         management group scope. Required.
        :type filter: str
        :return: An iterator like instance of either PolicyAssignment or the result of cls(response)
        :rtype:
         ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicyAssignmentListResult] = 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_policy_assignments_list_for_management_group_request(
                    management_group_id=management_group_id,
                    filter=filter,
                    api_version=api_version,
                    headers=_headers,
                    params=_params,
                )
                _request.url = self._client.format_url(_request.url)

            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._api_version
                _request = HttpRequest(
                    "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
                )
                _request.url = self._client.format_url(_request.url)
                _request.method = "GET"
            return _request

        async def extract_data(pipeline_response):
            deserialized = self._deserialize("PolicyAssignmentListResult", pipeline_response)
            list_of_elem = deserialized.value
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.next_link 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(  # 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)
                raise HttpResponseError(response=response, error_format=ARMErrorFormat)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)

    @distributed_trace
    def list(self, filter: Optional[str] = None, **kwargs: Any) -> AsyncItemPaged["_models.PolicyAssignment"]:
        """Retrieves all policy assignments that apply to a subscription.

        This operation retrieves the list of all policy assignments associated with the given
        subscription that match the optional given $filter. Valid values for $filter are: 'atScope()'
        or 'policyDefinitionId eq '{value}''. If $filter is not provided, the unfiltered list includes
        all policy assignments associated with the subscription, including those that apply directly or
        from management groups that contain the given subscription, as well as any applied to objects
        contained within the subscription. If $filter=atScope() is provided, the returned list includes
        all policy assignments that apply to the subscription, which is everything in the unfiltered
        list except those applied to objects contained within the subscription. If
        $filter=policyDefinitionId eq '{value}' is provided, the returned list includes all policy
        assignments of the policy definition whose id is {value}.

        :param filter: The filter to apply on the operation. Valid values for $filter are: 'atScope()'
         or 'policyDefinitionId eq '{value}''. If $filter is not provided, no filtering is performed.
         Default value is None.
        :type filter: str
        :return: An iterator like instance of either PolicyAssignment or the result of cls(response)
        :rtype:
         ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicyAssignmentListResult] = 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_policy_assignments_list_request(
                    subscription_id=self._config.subscription_id,
                    filter=filter,
                    api_version=api_version,
                    headers=_headers,
                    params=_params,
                )
                _request.url = self._client.format_url(_request.url)

            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._api_version
                _request = HttpRequest(
                    "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
                )
                _request.url = self._client.format_url(_request.url)
                _request.method = "GET"
            return _request

        async def extract_data(pipeline_response):
            deserialized = self._deserialize("PolicyAssignmentListResult", pipeline_response)
            list_of_elem = deserialized.value
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.next_link 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(  # 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)
                raise HttpResponseError(response=response, error_format=ARMErrorFormat)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)

    @distributed_trace_async
    async def delete_by_id(self, policy_assignment_id: str, **kwargs: Any) -> Optional[_models.PolicyAssignment]:
        """Deletes a policy assignment.

        This operation deletes the policy with the given ID. Policy assignment IDs have this format:
        '{scope}/providers/Microsoft.Authorization/policyAssignments/{policyAssignmentName}'. Valid
        formats for {scope} are: '/providers/Microsoft.Management/managementGroups/{managementGroup}'
        (management group), '/subscriptions/{subscriptionId}' (subscription),
        '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}' (resource group), or
        '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/[{parentResourcePath}/]{resourceType}/{resourceName}'
        (resource).

        :param policy_assignment_id: The ID of the policy assignment to delete. Use the format
         '{scope}/providers/Microsoft.Authorization/policyAssignments/{policyAssignmentName}'. Required.
        :type policy_assignment_id: str
        :return: PolicyAssignment or None or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment or 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 = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[Optional[_models.PolicyAssignment]] = kwargs.pop("cls", None)

        _request = build_policy_assignments_delete_by_id_request(
            policy_assignment_id=policy_assignment_id,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [200, 204]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

        deserialized = None
        if response.status_code == 200:
            deserialized = self._deserialize("PolicyAssignment", pipeline_response.http_response)

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

        return deserialized  # type: ignore

    @overload
    async def create_by_id(
        self,
        policy_assignment_id: str,
        parameters: _models.PolicyAssignment,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.PolicyAssignment:
        """Creates or updates a policy assignment.

        This operation creates or updates the policy assignment with the given ID. Policy assignments
        made on a scope apply to all resources contained in that scope. For example, when you assign a
        policy to a resource group that policy applies to all resources in the group. Policy assignment
        IDs have this format:
        '{scope}/providers/Microsoft.Authorization/policyAssignments/{policyAssignmentName}'. Valid
        scopes are: management group (format:
        '/providers/Microsoft.Management/managementGroups/{managementGroup}'), subscription (format:
        '/subscriptions/{subscriptionId}'), resource group (format:
        '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}', or resource (format:
        '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/[{parentResourcePath}/]{resourceType}/{resourceName}'.

        :param policy_assignment_id: The ID of the policy assignment to create. Use the format
         '{scope}/providers/Microsoft.Authorization/policyAssignments/{policyAssignmentName}'. Required.
        :type policy_assignment_id: str
        :param parameters: Parameters for policy assignment. Required.
        :type parameters: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: PolicyAssignment or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def create_by_id(
        self, policy_assignment_id: str, parameters: IO[bytes], *, content_type: str = "application/json", **kwargs: Any
    ) -> _models.PolicyAssignment:
        """Creates or updates a policy assignment.

        This operation creates or updates the policy assignment with the given ID. Policy assignments
        made on a scope apply to all resources contained in that scope. For example, when you assign a
        policy to a resource group that policy applies to all resources in the group. Policy assignment
        IDs have this format:
        '{scope}/providers/Microsoft.Authorization/policyAssignments/{policyAssignmentName}'. Valid
        scopes are: management group (format:
        '/providers/Microsoft.Management/managementGroups/{managementGroup}'), subscription (format:
        '/subscriptions/{subscriptionId}'), resource group (format:
        '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}', or resource (format:
        '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/[{parentResourcePath}/]{resourceType}/{resourceName}'.

        :param policy_assignment_id: The ID of the policy assignment to create. Use the format
         '{scope}/providers/Microsoft.Authorization/policyAssignments/{policyAssignmentName}'. Required.
        :type policy_assignment_id: str
        :param parameters: Parameters for policy assignment. 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: PolicyAssignment or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def create_by_id(
        self, policy_assignment_id: str, parameters: Union[_models.PolicyAssignment, IO[bytes]], **kwargs: Any
    ) -> _models.PolicyAssignment:
        """Creates or updates a policy assignment.

        This operation creates or updates the policy assignment with the given ID. Policy assignments
        made on a scope apply to all resources contained in that scope. For example, when you assign a
        policy to a resource group that policy applies to all resources in the group. Policy assignment
        IDs have this format:
        '{scope}/providers/Microsoft.Authorization/policyAssignments/{policyAssignmentName}'. Valid
        scopes are: management group (format:
        '/providers/Microsoft.Management/managementGroups/{managementGroup}'), subscription (format:
        '/subscriptions/{subscriptionId}'), resource group (format:
        '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}', or resource (format:
        '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/[{parentResourcePath}/]{resourceType}/{resourceName}'.

        :param policy_assignment_id: The ID of the policy assignment to create. Use the format
         '{scope}/providers/Microsoft.Authorization/policyAssignments/{policyAssignmentName}'. Required.
        :type policy_assignment_id: str
        :param parameters: Parameters for policy assignment. Is either a PolicyAssignment type or a
         IO[bytes] type. Required.
        :type parameters: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment or IO[bytes]
        :return: PolicyAssignment or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.PolicyAssignment] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _json = None
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _json = self._serialize.body(parameters, "PolicyAssignment")

        _request = build_policy_assignments_create_by_id_request(
            policy_assignment_id=policy_assignment_id,
            api_version=api_version,
            content_type=content_type,
            json=_json,
            content=_content,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [201]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

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

        return deserialized  # type: ignore

    @distributed_trace_async
    async def get_by_id(self, policy_assignment_id: str, **kwargs: Any) -> _models.PolicyAssignment:
        """Retrieves the policy assignment with the given ID.

        The operation retrieves the policy assignment with the given ID. Policy assignment IDs have
        this format:
        '{scope}/providers/Microsoft.Authorization/policyAssignments/{policyAssignmentName}'. Valid
        scopes are: management group (format:
        '/providers/Microsoft.Management/managementGroups/{managementGroup}'), subscription (format:
        '/subscriptions/{subscriptionId}'), resource group (format:
        '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}', or resource (format:
        '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/[{parentResourcePath}/]{resourceType}/{resourceName}'.

        :param policy_assignment_id: The ID of the policy assignment to get. Use the format
         '{scope}/providers/Microsoft.Authorization/policyAssignments/{policyAssignmentName}'. Required.
        :type policy_assignment_id: str
        :return: PolicyAssignment or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyAssignment
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicyAssignment] = kwargs.pop("cls", None)

        _request = build_policy_assignments_get_by_id_request(
            policy_assignment_id=policy_assignment_id,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

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

        return deserialized  # type: ignore


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

        Instead, you should access the following operations through
        :class:`~azure.mgmt.resource.policy.v2019_09_01.aio.PolicyClient`'s
        :attr:`policy_definitions` attribute.
    """

    models = _models

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

    @overload
    async def create_or_update(
        self,
        policy_definition_name: str,
        parameters: _models.PolicyDefinition,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.PolicyDefinition:
        """Creates or updates a policy definition in a subscription.

        This operation creates or updates a policy definition in the given subscription with the given
        name.

        :param policy_definition_name: The name of the policy definition to create. Required.
        :type policy_definition_name: str
        :param parameters: The policy definition properties. Required.
        :type parameters: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyDefinition
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: PolicyDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def create_or_update(
        self,
        policy_definition_name: str,
        parameters: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.PolicyDefinition:
        """Creates or updates a policy definition in a subscription.

        This operation creates or updates a policy definition in the given subscription with the given
        name.

        :param policy_definition_name: The name of the policy definition to create. Required.
        :type policy_definition_name: str
        :param parameters: The policy definition properties. 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: PolicyDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def create_or_update(
        self, policy_definition_name: str, parameters: Union[_models.PolicyDefinition, IO[bytes]], **kwargs: Any
    ) -> _models.PolicyDefinition:
        """Creates or updates a policy definition in a subscription.

        This operation creates or updates a policy definition in the given subscription with the given
        name.

        :param policy_definition_name: The name of the policy definition to create. Required.
        :type policy_definition_name: str
        :param parameters: The policy definition properties. Is either a PolicyDefinition type or a
         IO[bytes] type. Required.
        :type parameters: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyDefinition or IO[bytes]
        :return: PolicyDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.PolicyDefinition] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _json = None
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _json = self._serialize.body(parameters, "PolicyDefinition")

        _request = build_policy_definitions_create_or_update_request(
            policy_definition_name=policy_definition_name,
            subscription_id=self._config.subscription_id,
            api_version=api_version,
            content_type=content_type,
            json=_json,
            content=_content,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [201]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

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

        return deserialized  # type: ignore

    @distributed_trace_async
    async def delete(self, policy_definition_name: str, **kwargs: Any) -> None:
        """Deletes a policy definition in a subscription.

        This operation deletes the policy definition in the given subscription with the given name.

        :param policy_definition_name: The name of the policy definition to delete. Required.
        :type policy_definition_name: str
        :return: None or the result of cls(response)
        :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 = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[None] = kwargs.pop("cls", None)

        _request = build_policy_definitions_delete_request(
            policy_definition_name=policy_definition_name,
            subscription_id=self._config.subscription_id,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [200, 204]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

    @distributed_trace_async
    async def get(self, policy_definition_name: str, **kwargs: Any) -> _models.PolicyDefinition:
        """Retrieves a policy definition in a subscription.

        This operation retrieves the policy definition in the given subscription with the given name.

        :param policy_definition_name: The name of the policy definition to get. Required.
        :type policy_definition_name: str
        :return: PolicyDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicyDefinition] = kwargs.pop("cls", None)

        _request = build_policy_definitions_get_request(
            policy_definition_name=policy_definition_name,
            subscription_id=self._config.subscription_id,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

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

        return deserialized  # type: ignore

    @distributed_trace_async
    async def get_built_in(self, policy_definition_name: str, **kwargs: Any) -> _models.PolicyDefinition:
        """Retrieves a built-in policy definition.

        This operation retrieves the built-in policy definition with the given name.

        :param policy_definition_name: The name of the built-in policy definition to get. Required.
        :type policy_definition_name: str
        :return: PolicyDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicyDefinition] = kwargs.pop("cls", None)

        _request = build_policy_definitions_get_built_in_request(
            policy_definition_name=policy_definition_name,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

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

        return deserialized  # type: ignore

    @overload
    async def create_or_update_at_management_group(
        self,
        policy_definition_name: str,
        management_group_id: str,
        parameters: _models.PolicyDefinition,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.PolicyDefinition:
        """Creates or updates a policy definition in a management group.

        This operation creates or updates a policy definition in the given management group with the
        given name.

        :param policy_definition_name: The name of the policy definition to create. Required.
        :type policy_definition_name: str
        :param management_group_id: The ID of the management group. Required.
        :type management_group_id: str
        :param parameters: The policy definition properties. Required.
        :type parameters: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyDefinition
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: PolicyDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def create_or_update_at_management_group(
        self,
        policy_definition_name: str,
        management_group_id: str,
        parameters: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.PolicyDefinition:
        """Creates or updates a policy definition in a management group.

        This operation creates or updates a policy definition in the given management group with the
        given name.

        :param policy_definition_name: The name of the policy definition to create. Required.
        :type policy_definition_name: str
        :param management_group_id: The ID of the management group. Required.
        :type management_group_id: str
        :param parameters: The policy definition properties. 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: PolicyDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def create_or_update_at_management_group(
        self,
        policy_definition_name: str,
        management_group_id: str,
        parameters: Union[_models.PolicyDefinition, IO[bytes]],
        **kwargs: Any
    ) -> _models.PolicyDefinition:
        """Creates or updates a policy definition in a management group.

        This operation creates or updates a policy definition in the given management group with the
        given name.

        :param policy_definition_name: The name of the policy definition to create. Required.
        :type policy_definition_name: str
        :param management_group_id: The ID of the management group. Required.
        :type management_group_id: str
        :param parameters: The policy definition properties. Is either a PolicyDefinition type or a
         IO[bytes] type. Required.
        :type parameters: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyDefinition or IO[bytes]
        :return: PolicyDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.PolicyDefinition] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _json = None
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _json = self._serialize.body(parameters, "PolicyDefinition")

        _request = build_policy_definitions_create_or_update_at_management_group_request(
            policy_definition_name=policy_definition_name,
            management_group_id=management_group_id,
            api_version=api_version,
            content_type=content_type,
            json=_json,
            content=_content,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [201]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

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

        return deserialized  # type: ignore

    @distributed_trace_async
    async def delete_at_management_group(
        self, policy_definition_name: str, management_group_id: str, **kwargs: Any
    ) -> None:
        """Deletes a policy definition in a management group.

        This operation deletes the policy definition in the given management group with the given name.

        :param policy_definition_name: The name of the policy definition to delete. Required.
        :type policy_definition_name: str
        :param management_group_id: The ID of the management group. Required.
        :type management_group_id: str
        :return: None or the result of cls(response)
        :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 = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[None] = kwargs.pop("cls", None)

        _request = build_policy_definitions_delete_at_management_group_request(
            policy_definition_name=policy_definition_name,
            management_group_id=management_group_id,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [200, 204]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

    @distributed_trace_async
    async def get_at_management_group(
        self, policy_definition_name: str, management_group_id: str, **kwargs: Any
    ) -> _models.PolicyDefinition:
        """Retrieve a policy definition in a management group.

        This operation retrieves the policy definition in the given management group with the given
        name.

        :param policy_definition_name: The name of the policy definition to get. Required.
        :type policy_definition_name: str
        :param management_group_id: The ID of the management group. Required.
        :type management_group_id: str
        :return: PolicyDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicyDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicyDefinition] = kwargs.pop("cls", None)

        _request = build_policy_definitions_get_at_management_group_request(
            policy_definition_name=policy_definition_name,
            management_group_id=management_group_id,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

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

        return deserialized  # type: ignore

    @distributed_trace
    def list(self, **kwargs: Any) -> AsyncItemPaged["_models.PolicyDefinition"]:
        """Retrieves policy definitions in a subscription.

        This operation retrieves a list of all the policy definitions in a given subscription.

        :return: An iterator like instance of either PolicyDefinition or the result of cls(response)
        :rtype:
         ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.resource.policy.v2019_09_01.models.PolicyDefinition]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicyDefinitionListResult] = 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_policy_definitions_list_request(
                    subscription_id=self._config.subscription_id,
                    api_version=api_version,
                    headers=_headers,
                    params=_params,
                )
                _request.url = self._client.format_url(_request.url)

            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._api_version
                _request = HttpRequest(
                    "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
                )
                _request.url = self._client.format_url(_request.url)
                _request.method = "GET"
            return _request

        async def extract_data(pipeline_response):
            deserialized = self._deserialize("PolicyDefinitionListResult", pipeline_response)
            list_of_elem = deserialized.value
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.next_link 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(  # 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)
                raise HttpResponseError(response=response, error_format=ARMErrorFormat)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)

    @distributed_trace
    def list_built_in(self, **kwargs: Any) -> AsyncItemPaged["_models.PolicyDefinition"]:
        """Retrieve built-in policy definitions.

        This operation retrieves a list of all the built-in policy definitions.

        :return: An iterator like instance of either PolicyDefinition or the result of cls(response)
        :rtype:
         ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.resource.policy.v2019_09_01.models.PolicyDefinition]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicyDefinitionListResult] = 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_policy_definitions_list_built_in_request(
                    api_version=api_version,
                    headers=_headers,
                    params=_params,
                )
                _request.url = self._client.format_url(_request.url)

            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._api_version
                _request = HttpRequest(
                    "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
                )
                _request.url = self._client.format_url(_request.url)
                _request.method = "GET"
            return _request

        async def extract_data(pipeline_response):
            deserialized = self._deserialize("PolicyDefinitionListResult", pipeline_response)
            list_of_elem = deserialized.value
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.next_link 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(  # 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)
                raise HttpResponseError(response=response, error_format=ARMErrorFormat)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)

    @distributed_trace
    def list_by_management_group(
        self, management_group_id: str, **kwargs: Any
    ) -> AsyncItemPaged["_models.PolicyDefinition"]:
        """Retrieve policy definitions in a management group.

        This operation retrieves a list of all the policy definitions in a given management group.

        :param management_group_id: The ID of the management group. Required.
        :type management_group_id: str
        :return: An iterator like instance of either PolicyDefinition or the result of cls(response)
        :rtype:
         ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.resource.policy.v2019_09_01.models.PolicyDefinition]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicyDefinitionListResult] = 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_policy_definitions_list_by_management_group_request(
                    management_group_id=management_group_id,
                    api_version=api_version,
                    headers=_headers,
                    params=_params,
                )
                _request.url = self._client.format_url(_request.url)

            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._api_version
                _request = HttpRequest(
                    "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
                )
                _request.url = self._client.format_url(_request.url)
                _request.method = "GET"
            return _request

        async def extract_data(pipeline_response):
            deserialized = self._deserialize("PolicyDefinitionListResult", pipeline_response)
            list_of_elem = deserialized.value
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.next_link 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(  # 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)
                raise HttpResponseError(response=response, error_format=ARMErrorFormat)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)


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

        Instead, you should access the following operations through
        :class:`~azure.mgmt.resource.policy.v2019_09_01.aio.PolicyClient`'s
        :attr:`policy_set_definitions` attribute.
    """

    models = _models

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

    @overload
    async def create_or_update(
        self,
        policy_set_definition_name: str,
        parameters: _models.PolicySetDefinition,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.PolicySetDefinition:
        """Creates or updates a policy set definition.

        This operation creates or updates a policy set definition in the given subscription with the
        given name.

        :param policy_set_definition_name: The name of the policy set definition to create. Required.
        :type policy_set_definition_name: str
        :param parameters: The policy set definition properties. Required.
        :type parameters: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicySetDefinition
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: PolicySetDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicySetDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def create_or_update(
        self,
        policy_set_definition_name: str,
        parameters: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.PolicySetDefinition:
        """Creates or updates a policy set definition.

        This operation creates or updates a policy set definition in the given subscription with the
        given name.

        :param policy_set_definition_name: The name of the policy set definition to create. Required.
        :type policy_set_definition_name: str
        :param parameters: The policy set definition properties. 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: PolicySetDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicySetDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def create_or_update(
        self, policy_set_definition_name: str, parameters: Union[_models.PolicySetDefinition, IO[bytes]], **kwargs: Any
    ) -> _models.PolicySetDefinition:
        """Creates or updates a policy set definition.

        This operation creates or updates a policy set definition in the given subscription with the
        given name.

        :param policy_set_definition_name: The name of the policy set definition to create. Required.
        :type policy_set_definition_name: str
        :param parameters: The policy set definition properties. Is either a PolicySetDefinition type
         or a IO[bytes] type. Required.
        :type parameters: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicySetDefinition or
         IO[bytes]
        :return: PolicySetDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicySetDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.PolicySetDefinition] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _json = None
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _json = self._serialize.body(parameters, "PolicySetDefinition")

        _request = build_policy_set_definitions_create_or_update_request(
            policy_set_definition_name=policy_set_definition_name,
            subscription_id=self._config.subscription_id,
            api_version=api_version,
            content_type=content_type,
            json=_json,
            content=_content,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [200, 201]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

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

        return deserialized  # type: ignore

    @distributed_trace_async
    async def delete(self, policy_set_definition_name: str, **kwargs: Any) -> None:
        """Deletes a policy set definition.

        This operation deletes the policy set definition in the given subscription with the given name.

        :param policy_set_definition_name: The name of the policy set definition to delete. Required.
        :type policy_set_definition_name: str
        :return: None or the result of cls(response)
        :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 = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[None] = kwargs.pop("cls", None)

        _request = build_policy_set_definitions_delete_request(
            policy_set_definition_name=policy_set_definition_name,
            subscription_id=self._config.subscription_id,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [200, 204]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

    @distributed_trace_async
    async def get(self, policy_set_definition_name: str, **kwargs: Any) -> _models.PolicySetDefinition:
        """Retrieves a policy set definition.

        This operation retrieves the policy set definition in the given subscription with the given
        name.

        :param policy_set_definition_name: The name of the policy set definition to get. Required.
        :type policy_set_definition_name: str
        :return: PolicySetDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicySetDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicySetDefinition] = kwargs.pop("cls", None)

        _request = build_policy_set_definitions_get_request(
            policy_set_definition_name=policy_set_definition_name,
            subscription_id=self._config.subscription_id,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

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

        return deserialized  # type: ignore

    @distributed_trace_async
    async def get_built_in(self, policy_set_definition_name: str, **kwargs: Any) -> _models.PolicySetDefinition:
        """Retrieves a built in policy set definition.

        This operation retrieves the built-in policy set definition with the given name.

        :param policy_set_definition_name: The name of the policy set definition to get. Required.
        :type policy_set_definition_name: str
        :return: PolicySetDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicySetDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicySetDefinition] = kwargs.pop("cls", None)

        _request = build_policy_set_definitions_get_built_in_request(
            policy_set_definition_name=policy_set_definition_name,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

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

        return deserialized  # type: ignore

    @distributed_trace
    def list(self, **kwargs: Any) -> AsyncItemPaged["_models.PolicySetDefinition"]:
        """Retrieves the policy set definitions for a subscription.

        This operation retrieves a list of all the policy set definitions in the given subscription.

        :return: An iterator like instance of either PolicySetDefinition or the result of cls(response)
        :rtype:
         ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.resource.policy.v2019_09_01.models.PolicySetDefinition]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicySetDefinitionListResult] = 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_policy_set_definitions_list_request(
                    subscription_id=self._config.subscription_id,
                    api_version=api_version,
                    headers=_headers,
                    params=_params,
                )
                _request.url = self._client.format_url(_request.url)

            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._api_version
                _request = HttpRequest(
                    "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
                )
                _request.url = self._client.format_url(_request.url)
                _request.method = "GET"
            return _request

        async def extract_data(pipeline_response):
            deserialized = self._deserialize("PolicySetDefinitionListResult", pipeline_response)
            list_of_elem = deserialized.value
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.next_link 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(  # 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)
                raise HttpResponseError(response=response, error_format=ARMErrorFormat)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)

    @distributed_trace
    def list_built_in(self, **kwargs: Any) -> AsyncItemPaged["_models.PolicySetDefinition"]:
        """Retrieves built-in policy set definitions.

        This operation retrieves a list of all the built-in policy set definitions.

        :return: An iterator like instance of either PolicySetDefinition or the result of cls(response)
        :rtype:
         ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.resource.policy.v2019_09_01.models.PolicySetDefinition]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicySetDefinitionListResult] = 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_policy_set_definitions_list_built_in_request(
                    api_version=api_version,
                    headers=_headers,
                    params=_params,
                )
                _request.url = self._client.format_url(_request.url)

            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._api_version
                _request = HttpRequest(
                    "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
                )
                _request.url = self._client.format_url(_request.url)
                _request.method = "GET"
            return _request

        async def extract_data(pipeline_response):
            deserialized = self._deserialize("PolicySetDefinitionListResult", pipeline_response)
            list_of_elem = deserialized.value
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.next_link 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(  # 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)
                raise HttpResponseError(response=response, error_format=ARMErrorFormat)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)

    @overload
    async def create_or_update_at_management_group(
        self,
        policy_set_definition_name: str,
        management_group_id: str,
        parameters: _models.PolicySetDefinition,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.PolicySetDefinition:
        """Creates or updates a policy set definition.

        This operation creates or updates a policy set definition in the given management group with
        the given name.

        :param policy_set_definition_name: The name of the policy set definition to create. Required.
        :type policy_set_definition_name: str
        :param management_group_id: The ID of the management group. Required.
        :type management_group_id: str
        :param parameters: The policy set definition properties. Required.
        :type parameters: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicySetDefinition
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: PolicySetDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicySetDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def create_or_update_at_management_group(
        self,
        policy_set_definition_name: str,
        management_group_id: str,
        parameters: IO[bytes],
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.PolicySetDefinition:
        """Creates or updates a policy set definition.

        This operation creates or updates a policy set definition in the given management group with
        the given name.

        :param policy_set_definition_name: The name of the policy set definition to create. Required.
        :type policy_set_definition_name: str
        :param management_group_id: The ID of the management group. Required.
        :type management_group_id: str
        :param parameters: The policy set definition properties. 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: PolicySetDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicySetDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def create_or_update_at_management_group(
        self,
        policy_set_definition_name: str,
        management_group_id: str,
        parameters: Union[_models.PolicySetDefinition, IO[bytes]],
        **kwargs: Any
    ) -> _models.PolicySetDefinition:
        """Creates or updates a policy set definition.

        This operation creates or updates a policy set definition in the given management group with
        the given name.

        :param policy_set_definition_name: The name of the policy set definition to create. Required.
        :type policy_set_definition_name: str
        :param management_group_id: The ID of the management group. Required.
        :type management_group_id: str
        :param parameters: The policy set definition properties. Is either a PolicySetDefinition type
         or a IO[bytes] type. Required.
        :type parameters: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicySetDefinition or
         IO[bytes]
        :return: PolicySetDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicySetDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.PolicySetDefinition] = kwargs.pop("cls", None)

        content_type = content_type or "application/json"
        _json = None
        _content = None
        if isinstance(parameters, (IOBase, bytes)):
            _content = parameters
        else:
            _json = self._serialize.body(parameters, "PolicySetDefinition")

        _request = build_policy_set_definitions_create_or_update_at_management_group_request(
            policy_set_definition_name=policy_set_definition_name,
            management_group_id=management_group_id,
            api_version=api_version,
            content_type=content_type,
            json=_json,
            content=_content,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [200, 201]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

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

        return deserialized  # type: ignore

    @distributed_trace_async
    async def delete_at_management_group(
        self, policy_set_definition_name: str, management_group_id: str, **kwargs: Any
    ) -> None:
        """Deletes a policy set definition.

        This operation deletes the policy set definition in the given management group with the given
        name.

        :param policy_set_definition_name: The name of the policy set definition to delete. Required.
        :type policy_set_definition_name: str
        :param management_group_id: The ID of the management group. Required.
        :type management_group_id: str
        :return: None or the result of cls(response)
        :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 = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[None] = kwargs.pop("cls", None)

        _request = build_policy_set_definitions_delete_at_management_group_request(
            policy_set_definition_name=policy_set_definition_name,
            management_group_id=management_group_id,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [200, 204]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

    @distributed_trace_async
    async def get_at_management_group(
        self, policy_set_definition_name: str, management_group_id: str, **kwargs: Any
    ) -> _models.PolicySetDefinition:
        """Retrieves a policy set definition.

        This operation retrieves the policy set definition in the given management group with the given
        name.

        :param policy_set_definition_name: The name of the policy set definition to get. Required.
        :type policy_set_definition_name: str
        :param management_group_id: The ID of the management group. Required.
        :type management_group_id: str
        :return: PolicySetDefinition or the result of cls(response)
        :rtype: ~azure.mgmt.resource.policy.v2019_09_01.models.PolicySetDefinition
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map: MutableMapping = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicySetDefinition] = kwargs.pop("cls", None)

        _request = build_policy_set_definitions_get_at_management_group_request(
            policy_set_definition_name=policy_set_definition_name,
            management_group_id=management_group_id,
            api_version=api_version,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [200]:
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response, error_format=ARMErrorFormat)

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

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

        return deserialized  # type: ignore

    @distributed_trace
    def list_by_management_group(
        self, management_group_id: str, **kwargs: Any
    ) -> AsyncItemPaged["_models.PolicySetDefinition"]:
        """Retrieves all policy set definitions in management group.

        This operation retrieves a list of all the a policy set definition in the given management
        group.

        :param management_group_id: The ID of the management group. Required.
        :type management_group_id: str
        :return: An iterator like instance of either PolicySetDefinition or the result of cls(response)
        :rtype:
         ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.resource.policy.v2019_09_01.models.PolicySetDefinition]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: str = kwargs.pop("api_version", _params.pop("api-version", self._api_version or "2019-09-01"))
        cls: ClsType[_models.PolicySetDefinitionListResult] = 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_policy_set_definitions_list_by_management_group_request(
                    management_group_id=management_group_id,
                    api_version=api_version,
                    headers=_headers,
                    params=_params,
                )
                _request.url = self._client.format_url(_request.url)

            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._api_version
                _request = HttpRequest(
                    "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params
                )
                _request.url = self._client.format_url(_request.url)
                _request.method = "GET"
            return _request

        async def extract_data(pipeline_response):
            deserialized = self._deserialize("PolicySetDefinitionListResult", pipeline_response)
            list_of_elem = deserialized.value
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.next_link 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(  # 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)
                raise HttpResponseError(response=response, error_format=ARMErrorFormat)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)
