text: # 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 typing import TYPE_CHECKING
  import warnings
  
  from azure.core.exceptions import HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error
  from azure.core.paging import ItemPaged
  from azure.core.pipeline import PipelineResponse
  from azure.core.pipeline.transport import HttpRequest, HttpResponse
  from azure.mgmt.core.exceptions import ARMErrorFormat
  
  from .. import models
  
  if TYPE_CHECKING:
      # pylint: disable=unused-import,ungrouped-imports
      from typing import Any, Callable, Dict, Generic, Iterable, Optional, TypeVar, Union
  
      T = TypeVar('T')
      ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]]
  
  class TagsOperations(object):
      """TagsOperations operations.
  
      You should not instantiate this class directly. Instead, you should create a Client instance that
      instantiates it for you and attaches it as an attribute.
  
      :ivar models: Alias to model classes used in this operation group.
      :type models: ~azure.mgmt.resource.resources.v2019_10_01.models
      :param client: Client for service requests.
      :param config: Configuration of service client.
      :param serializer: An object model serializer.
      :param deserializer: An object model deserializer.
      """
  
      models = models
  
      def __init__(self, client, config, serializer, deserializer):
          self._client = client
          self._serialize = serializer
          self._deserialize = deserializer
          self._config = config
  
      def delete_value(
          self,
          tag_name,  # type: str
          tag_value,  # type: str
          **kwargs  # type: Any
      ):
          # type: (...) -> None
          """Deletes a predefined tag value for a predefined tag name.
  
          This operation allows deleting a value from the list of predefined values for an existing
          predefined tag name. The value being deleted must not be in use as a tag value for the given
          tag name for any resource.
  
          :param tag_name: The name of the tag.
          :type tag_name: str
          :param tag_value: The value of the tag to delete.
          :type tag_value: str
          :keyword callable cls: A custom type or function that will be passed the direct response
          :return: None, or the result of cls(response)
          :rtype: None
          :raises: ~azure.core.exceptions.HttpResponseError
          """
          cls = kwargs.pop('cls', None)  # type: ClsType[None]
          error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
          error_map.update(kwargs.pop('error_map', {}))
          api_version = "2019-10-01"
  
          # Construct URL
          url = self.delete_value.metadata['url']  # type: ignore
          path_format_arguments = {
              'tagName': self._serialize.url("tag_name", tag_name, 'str'),
              'tagValue': self._serialize.url("tag_value", tag_value, 'str'),
              'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str'),
          }
          url = self._client.format_url(url, **path_format_arguments)
  
          # Construct parameters
          query_parameters = {}  # type: Dict[str, Any]
          query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str')
  
          # Construct headers
          header_parameters = {}  # type: Dict[str, Any]
  
          # Construct and send request
          request = self._client.delete(url, query_parameters, header_parameters)
          pipeline_response = self._client._pipeline.run(request, stream=False, **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, {})
  
      delete_value.metadata = {'url': '/subscriptions/{subscriptionId}/tagNames/{tagName}/tagValues/{tagValue}'}  # type: ignore
  
      def create_or_update_value(
          self,
          tag_name,  # type: str
          tag_value,  # type: str
          **kwargs  # type: Any
      ):
          # type: (...) -> "models.TagValue"
          """Creates a predefined value for a predefined tag name.
  
          This operation allows adding a value to the list of predefined values for an existing
          predefined tag name. A tag value can have a maximum of 256 characters.
  
          :param tag_name: The name of the tag.
          :type tag_name: str
          :param tag_value: The value of the tag to create.
          :type tag_value: str
          :keyword callable cls: A custom type or function that will be passed the direct response
          :return: TagValue, or the result of cls(response)
          :rtype: ~azure.mgmt.resource.resources.v2019_10_01.models.TagValue
          :raises: ~azure.core.exceptions.HttpResponseError
          """
          cls = kwargs.pop('cls', None)  # type: ClsType["models.TagValue"]
          error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
          error_map.update(kwargs.pop('error_map', {}))
          api_version = "2019-10-01"
  
          # Construct URL
          url = self.create_or_update_value.metadata['url']  # type: ignore
          path_format_arguments = {
              'tagName': self._serialize.url("tag_name", tag_name, 'str'),
              'tagValue': self._serialize.url("tag_value", tag_value, 'str'),
              'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str'),
          }
          url = self._client.format_url(url, **path_format_arguments)
  
          # Construct parameters
          query_parameters = {}  # type: Dict[str, Any]
          query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str')
  
          # Construct headers
          header_parameters = {}  # type: Dict[str, Any]
          header_parameters['Accept'] = 'application/json'
  
          # Construct and send request
          request = self._client.put(url, query_parameters, header_parameters)
          pipeline_response = self._client._pipeline.run(request, stream=False, **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 = None
          if response.status_code == 200:
              deserialized = self._deserialize('TagValue', pipeline_response)
  
          if response.status_code == 201:
              deserialized = self._deserialize('TagValue', pipeline_response)
  
          if cls:
              return cls(pipeline_response, deserialized, {})
  
          return deserialized
      create_or_update_value.metadata = {'url': '/subscriptions/{subscriptionId}/tagNames/{tagName}/tagValues/{tagValue}'}  # type: ignore
  
      def create_or_update(
          self,
          tag_name,  # type: str
          **kwargs  # type: Any
      ):
          # type: (...) -> "models.TagDetails"
          """Creates a predefined tag name.
  
          This operation allows adding a name to the list of predefined tag names for the given
          subscription. A tag name can have a maximum of 512 characters and is case-insensitive. Tag
          names cannot have the following prefixes which are reserved for Azure use: 'microsoft',
          'azure', 'windows'.
  
          :param tag_name: The name of the tag to create.
          :type tag_name: str
          :keyword callable cls: A custom type or function that will be passed the direct response
          :return: TagDetails, or the result of cls(response)
          :rtype: ~azure.mgmt.resource.resources.v2019_10_01.models.TagDetails
          :raises: ~azure.core.exceptions.HttpResponseError
          """
          cls = kwargs.pop('cls', None)  # type: ClsType["models.TagDetails"]
          error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
          error_map.update(kwargs.pop('error_map', {}))
          api_version = "2019-10-01"
  
          # Construct URL
          url = self.create_or_update.metadata['url']  # type: ignore
          path_format_arguments = {
              'tagName': self._serialize.url("tag_name", tag_name, 'str'),
              'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str'),
          }
          url = self._client.format_url(url, **path_format_arguments)
  
          # Construct parameters
          query_parameters = {}  # type: Dict[str, Any]
          query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str')
  
          # Construct headers
          header_parameters = {}  # type: Dict[str, Any]
          header_parameters['Accept'] = 'application/json'
  
          # Construct and send request
          request = self._client.put(url, query_parameters, header_parameters)
          pipeline_response = self._client._pipeline.run(request, stream=False, **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 = None
          if response.status_code == 200:
              deserialized = self._deserialize('TagDetails', pipeline_response)
  
          if response.status_code == 201:
              deserialized = self._deserialize('TagDetails', pipeline_response)
  
          if cls:
              return cls(pipeline_response, deserialized, {})
  
          return deserialized
      create_or_update.metadata = {'url': '/subscriptions/{subscriptionId}/tagNames/{tagName}'}  # type: ignore
  
      def delete(
          self,
          tag_name,  # type: str
          **kwargs  # type: Any
      ):
          # type: (...) -> None
          """Deletes a predefined tag name.
  
          This operation allows deleting a name from the list of predefined tag names for the given
          subscription. The name being deleted must not be in use as a tag name for any resource. All
          predefined values for the given name must have already been deleted.
  
          :param tag_name: The name of the tag.
          :type tag_name: str
          :keyword callable cls: A custom type or function that will be passed the direct response
          :return: None, or the result of cls(response)
          :rtype: None
          :raises: ~azure.core.exceptions.HttpResponseError
          """
          cls = kwargs.pop('cls', None)  # type: ClsType[None]
          error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
          error_map.update(kwargs.pop('error_map', {}))
          api_version = "2019-10-01"
  
          # Construct URL
          url = self.delete.metadata['url']  # type: ignore
          path_format_arguments = {
              'tagName': self._serialize.url("tag_name", tag_name, 'str'),
              'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str'),
          }
          url = self._client.format_url(url, **path_format_arguments)
  
          # Construct parameters
          query_parameters = {}  # type: Dict[str, Any]
          query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str')
  
          # Construct headers
          header_parameters = {}  # type: Dict[str, Any]
  
          # Construct and send request
          request = self._client.delete(url, query_parameters, header_parameters)
          pipeline_response = self._client._pipeline.run(request, stream=False, **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, {})
  
      delete.metadata = {'url': '/subscriptions/{subscriptionId}/tagNames/{tagName}'}  # type: ignore
  
      def list(
          self,
          **kwargs  # type: Any
      ):
          # type: (...) -> Iterable["models.TagsListResult"]
          """Gets a summary of tag usage under the subscription.
  
          This operation performs a union of predefined tags, resource tags, resource group tags and
      subscription tags, and returns a summary of usage for each tag name and value under the given
      subscription. In case of a large number of tags, this operation may return a previously cached
      result.
  
          :keyword callable cls: A custom type or function that will be passed the direct response
          :return: An iterator like instance of either TagsListResult or the result of cls(response)
          :rtype: ~azure.core.paging.ItemPaged[~azure.mgmt.resource.resources.v2019_10_01.models.TagsListResult]
          :raises: ~azure.core.exceptions.HttpResponseError
          """
          cls = kwargs.pop('cls', None)  # type: ClsType["models.TagsListResult"]
          error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
          error_map.update(kwargs.pop('error_map', {}))
          api_version = "2019-10-01"
  
          def prepare_request(next_link=None):
              if not next_link:
                  # Construct URL
                  url = self.list.metadata['url']  # type: ignore
                  path_format_arguments = {
                      'subscriptionId': self._serialize.url("self._config.subscription_id", self._config.subscription_id, 'str'),
                  }
                  url = self._client.format_url(url, **path_format_arguments)
                  # Construct parameters
                  query_parameters = {}  # type: Dict[str, Any]
                  query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str')
  
              else:
                  url = next_link
                  query_parameters = {}  # type: Dict[str, Any]
              # Construct headers
              header_parameters = {}  # type: Dict[str, Any]
              header_parameters['Accept'] = 'application/json'
  
              # Construct and send request
              request = self._client.get(url, query_parameters, header_parameters)
              return request
  
          def extract_data(pipeline_response):
              deserialized = self._deserialize('TagsListResult', pipeline_response)
              list_of_elem = deserialized.value
              if cls:
                  list_of_elem = cls(list_of_elem)
              return deserialized.next_link or None, iter(list_of_elem)
  
          def get_next(next_link=None):
              request = prepare_request(next_link)
  
              pipeline_response = self._client._pipeline.run(request, stream=False, **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 ItemPaged(
              get_next, extract_data
          )
      list.metadata = {'url': '/subscriptions/{subscriptionId}/tagNames'}  # type: ignore
  
      def create_or_update_at_scope(
          self,
          scope,  # type: str
          parameters,  # type: "models.TagsResource"
          **kwargs  # type: Any
      ):
          # type: (...) -> "models.TagsResource"
          """Creates or updates the entire set of tags on a resource or subscription.
  
          This operation allows adding or replacing the entire set of tags on the specified resource or
          subscription. The specified entity can have a maximum of 50 tags.
  
          :param scope: The resource scope.
          :type scope: str
          :param parameters:
          :type parameters: ~azure.mgmt.resource.resources.v2019_10_01.models.TagsResource
          :keyword callable cls: A custom type or function that will be passed the direct response
          :return: TagsResource, or the result of cls(response)
          :rtype: ~azure.mgmt.resource.resources.v2019_10_01.models.TagsResource
          :raises: ~azure.core.exceptions.HttpResponseError
          """
          cls = kwargs.pop('cls', None)  # type: ClsType["models.TagsResource"]
          error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
          error_map.update(kwargs.pop('error_map', {}))
          api_version = "2019-10-01"
          content_type = kwargs.pop("content_type", "application/json")
  
          # Construct URL
          url = self.create_or_update_at_scope.metadata['url']  # type: ignore
          path_format_arguments = {
              'scope': self._serialize.url("scope", scope, 'str', skip_quote=True),
          }
          url = self._client.format_url(url, **path_format_arguments)
  
          # Construct parameters
          query_parameters = {}  # type: Dict[str, Any]
          query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str')
  
          # Construct headers
          header_parameters = {}  # type: Dict[str, Any]
          header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
          header_parameters['Accept'] = 'application/json'
  
          # Construct and send request
          body_content_kwargs = {}  # type: Dict[str, Any]
          body_content = self._serialize.body(parameters, 'TagsResource')
          body_content_kwargs['content'] = body_content
          request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs)
  
          pipeline_response = self._client._pipeline.run(request, stream=False, **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('TagsResource', pipeline_response)
  
          if cls:
              return cls(pipeline_response, deserialized, {})
  
          return deserialized
      create_or_update_at_scope.metadata = {'url': '/{scope}/providers/Microsoft.Resources/tags/default'}  # type: ignore
  
      def update_at_scope(
          self,
          scope,  # type: str
          parameters,  # type: "models.TagsPatchResource"
          **kwargs  # type: Any
      ):
          # type: (...) -> "models.TagsResource"
          """Selectively updates the set of tags on a resource or subscription.
  
          This operation allows replacing, merging or selectively deleting tags on the specified resource
          or subscription. The specified entity can have a maximum of 50 tags at the end of the
          operation. The 'replace' option replaces the entire set of existing tags with a new set. The
          'merge' option allows adding tags with new names and updating the values of tags with existing
          names. The 'delete' option allows selectively deleting tags based on given names or name/value
          pairs.
  
          :param scope: The resource scope.
          :type scope: str
          :param parameters:
          :type parameters: ~azure.mgmt.resource.resources.v2019_10_01.models.TagsPatchResource
          :keyword callable cls: A custom type or function that will be passed the direct response
          :return: TagsResource, or the result of cls(response)
          :rtype: ~azure.mgmt.resource.resources.v2019_10_01.models.TagsResource
          :raises: ~azure.core.exceptions.HttpResponseError
          """
          cls = kwargs.pop('cls', None)  # type: ClsType["models.TagsResource"]
          error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
          error_map.update(kwargs.pop('error_map', {}))
          api_version = "2019-10-01"
          content_type = kwargs.pop("content_type", "application/json")
  
          # Construct URL
          url = self.update_at_scope.metadata['url']  # type: ignore
          path_format_arguments = {
              'scope': self._serialize.url("scope", scope, 'str', skip_quote=True),
          }
          url = self._client.format_url(url, **path_format_arguments)
  
          # Construct parameters
          query_parameters = {}  # type: Dict[str, Any]
          query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str')
  
          # Construct headers
          header_parameters = {}  # type: Dict[str, Any]
          header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str')
          header_parameters['Accept'] = 'application/json'
  
          # Construct and send request
          body_content_kwargs = {}  # type: Dict[str, Any]
          body_content = self._serialize.body(parameters, 'TagsPatchResource')
          body_content_kwargs['content'] = body_content
          request = self._client.patch(url, query_parameters, header_parameters, **body_content_kwargs)
  
          pipeline_response = self._client._pipeline.run(request, stream=False, **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('TagsResource', pipeline_response)
  
          if cls:
              return cls(pipeline_response, deserialized, {})
  
          return deserialized
      update_at_scope.metadata = {'url': '/{scope}/providers/Microsoft.Resources/tags/default'}  # type: ignore
  
      def get_at_scope(
          self,
          scope,  # type: str
          **kwargs  # type: Any
      ):
          # type: (...) -> "models.TagsResource"
          """Gets the entire set of tags on a resource or subscription.
  
          Gets the entire set of tags on a resource or subscription.
  
          :param scope: The resource scope.
          :type scope: str
          :keyword callable cls: A custom type or function that will be passed the direct response
          :return: TagsResource, or the result of cls(response)
          :rtype: ~azure.mgmt.resource.resources.v2019_10_01.models.TagsResource
          :raises: ~azure.core.exceptions.HttpResponseError
          """
          cls = kwargs.pop('cls', None)  # type: ClsType["models.TagsResource"]
          error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
          error_map.update(kwargs.pop('error_map', {}))
          api_version = "2019-10-01"
  
          # Construct URL
          url = self.get_at_scope.metadata['url']  # type: ignore
          path_format_arguments = {
              'scope': self._serialize.url("scope", scope, 'str', skip_quote=True),
          }
          url = self._client.format_url(url, **path_format_arguments)
  
          # Construct parameters
          query_parameters = {}  # type: Dict[str, Any]
          query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str')
  
          # Construct headers
          header_parameters = {}  # type: Dict[str, Any]
          header_parameters['Accept'] = 'application/json'
  
          # Construct and send request
          request = self._client.get(url, query_parameters, header_parameters)
          pipeline_response = self._client._pipeline.run(request, stream=False, **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('TagsResource', pipeline_response)
  
          if cls:
              return cls(pipeline_response, deserialized, {})
  
          return deserialized
      get_at_scope.metadata = {'url': '/{scope}/providers/Microsoft.Resources/tags/default'}  # type: ignore
  
      def delete_at_scope(
          self,
          scope,  # type: str
          **kwargs  # type: Any
      ):
          # type: (...) -> None
          """Deletes the entire set of tags on a resource or subscription.
  
          Deletes the entire set of tags on a resource or subscription.
  
          :param scope: The resource scope.
          :type scope: str
          :keyword callable cls: A custom type or function that will be passed the direct response
          :return: None, or the result of cls(response)
          :rtype: None
          :raises: ~azure.core.exceptions.HttpResponseError
          """
          cls = kwargs.pop('cls', None)  # type: ClsType[None]
          error_map = {404: ResourceNotFoundError, 409: ResourceExistsError}
          error_map.update(kwargs.pop('error_map', {}))
          api_version = "2019-10-01"
  
          # Construct URL
          url = self.delete_at_scope.metadata['url']  # type: ignore
          path_format_arguments = {
              'scope': self._serialize.url("scope", scope, 'str', skip_quote=True),
          }
          url = self._client.format_url(url, **path_format_arguments)
  
          # Construct parameters
          query_parameters = {}  # type: Dict[str, Any]
          query_parameters['api-version'] = self._serialize.query("api_version", api_version, 'str')
  
          # Construct headers
          header_parameters = {}  # type: Dict[str, Any]
  
          # Construct and send request
          request = self._client.delete(url, query_parameters, header_parameters)
          pipeline_response = self._client._pipeline.run(request, stream=False, **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)
  
          if cls:
              return cls(pipeline_response, None, {})
  
      delete_at_scope.metadata = {'url': '/{scope}/providers/Microsoft.Resources/tags/default'}  # type: ignore
  