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

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

from .._serialization import Serializer
from .._vendor import ClientMixinABC

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

_SERIALIZER = Serializer()
_SERIALIZER.client_side_validation = False


def build_ingest_events_request(**kwargs: Any) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})

    content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
    accept = _headers.pop("Accept", "application/problem+json")

    # Construct URL
    _url = "/api/v1/events"

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

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


def build_list_events_request(
    *,
    from_parameter: Optional[datetime.datetime] = None,
    to: Optional[datetime.datetime] = None,
    limit: Optional[int] = None,
    **kwargs: Any
) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
    _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

    accept = _headers.pop("Accept", "application/json, application/problem+json")

    # Construct URL
    _url = "/api/v1/events"

    # Construct parameters
    if from_parameter is not None:
        _params["from"] = _SERIALIZER.query("from_parameter", from_parameter, "iso-8601")
    if to is not None:
        _params["to"] = _SERIALIZER.query("to", to, "iso-8601")
    if limit is not None:
        _params["limit"] = _SERIALIZER.query("limit", limit, "int", maximum=100, minimum=1)

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

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


def build_list_meters_request(**kwargs: Any) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})

    accept = _headers.pop("Accept", "application/json, application/problem+json")

    # Construct URL
    _url = "/api/v1/meters"

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

    return HttpRequest(method="GET", url=_url, headers=_headers, **kwargs)


def build_create_meter_request(**kwargs: Any) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})

    content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
    accept = _headers.pop("Accept", "application/json, application/problem+json")

    # Construct URL
    _url = "/api/v1/meters"

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

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


def build_get_meter_request(meter_id_or_slug: str, **kwargs: Any) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})

    accept = _headers.pop("Accept", "application/json, application/problem+json")

    # Construct URL
    _url = "/api/v1/meters/{meterIdOrSlug}"
    path_format_arguments = {
        "meterIdOrSlug": _SERIALIZER.url("meter_id_or_slug", meter_id_or_slug, "str"),
    }

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

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

    return HttpRequest(method="GET", url=_url, headers=_headers, **kwargs)


def build_delete_meter_request(meter_id_or_slug: str, **kwargs: Any) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})

    accept = _headers.pop("Accept", "application/problem+json")

    # Construct URL
    _url = "/api/v1/meters/{meterIdOrSlug}"
    path_format_arguments = {
        "meterIdOrSlug": _SERIALIZER.url("meter_id_or_slug", meter_id_or_slug, "str"),
    }

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

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

    return HttpRequest(method="DELETE", url=_url, headers=_headers, **kwargs)


def build_query_meter_request(
    meter_id_or_slug: str,
    *,
    from_parameter: Optional[datetime.datetime] = None,
    to: Optional[datetime.datetime] = None,
    window_size: Optional[str] = None,
    window_time_zone: str = "UTC",
    subject: Optional[List[str]] = None,
    group_by: Optional[List[str]] = None,
    **kwargs: Any
) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
    _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

    accept = _headers.pop("Accept", "application/json, text/csv, application/problem+json")

    # Construct URL
    _url = "/api/v1/meters/{meterIdOrSlug}/query"
    path_format_arguments = {
        "meterIdOrSlug": _SERIALIZER.url("meter_id_or_slug", meter_id_or_slug, "str"),
    }

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

    # Construct parameters
    if from_parameter is not None:
        _params["from"] = _SERIALIZER.query("from_parameter", from_parameter, "iso-8601")
    if to is not None:
        _params["to"] = _SERIALIZER.query("to", to, "iso-8601")
    if window_size is not None:
        _params["windowSize"] = _SERIALIZER.query("window_size", window_size, "str")
    if window_time_zone is not None:
        _params["windowTimeZone"] = _SERIALIZER.query("window_time_zone", window_time_zone, "str")
    if subject is not None:
        _params["subject"] = _SERIALIZER.query("subject", subject, "[str]")
    if group_by is not None:
        _params["groupBy"] = _SERIALIZER.query("group_by", group_by, "[str]")

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

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


def build_list_meter_subjects_request(meter_id_or_slug: str, **kwargs: Any) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})

    accept = _headers.pop("Accept", "application/json, application/problem+json")

    # Construct URL
    _url = "/api/v1/meters/{meterIdOrSlug}/subjects"
    path_format_arguments = {
        "meterIdOrSlug": _SERIALIZER.url("meter_id_or_slug", meter_id_or_slug, "str"),
    }

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

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

    return HttpRequest(method="GET", url=_url, headers=_headers, **kwargs)


def build_create_portal_token_request(**kwargs: Any) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})

    content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
    accept = _headers.pop("Accept", "application/json, application/problem+json")

    # Construct URL
    _url = "/api/v1/portal/tokens"

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

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


def build_list_portal_tokens_request(*, limit: int = 25, **kwargs: Any) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
    _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

    accept = _headers.pop("Accept", "application/json, application/problem+json")

    # Construct URL
    _url = "/api/v1/portal/tokens"

    # Construct parameters
    if limit is not None:
        _params["limit"] = _SERIALIZER.query("limit", limit, "int", maximum=100, minimum=1)

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

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


def build_invalidate_portal_tokens_request(**kwargs: Any) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})

    content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
    accept = _headers.pop("Accept", "application/problem+json")

    # Construct URL
    _url = "/api/v1/portal/tokens/invalidate"

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

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


def build_list_subjects_request(**kwargs: Any) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})

    accept = _headers.pop("Accept", "application/json, application/problem+json")

    # Construct URL
    _url = "/api/v1/subjects"

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

    return HttpRequest(method="GET", url=_url, headers=_headers, **kwargs)


def build_upsert_subject_request(**kwargs: Any) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})

    content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
    accept = _headers.pop("Accept", "application/json, application/problem+json")

    # Construct URL
    _url = "/api/v1/subjects"

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

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


def build_get_subject_request(subject_id_or_key: str, **kwargs: Any) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})

    accept = _headers.pop("Accept", "application/json, application/problem+json")

    # Construct URL
    _url = "/api/v1/subjects/{subjectIdOrKey}"
    path_format_arguments = {
        "subjectIdOrKey": _SERIALIZER.url("subject_id_or_key", subject_id_or_key, "str"),
    }

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

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

    return HttpRequest(method="GET", url=_url, headers=_headers, **kwargs)


def build_delete_subject_request(subject_id_or_key: str, **kwargs: Any) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})

    accept = _headers.pop("Accept", "application/problem+json")

    # Construct URL
    _url = "/api/v1/subjects/{subjectIdOrKey}"
    path_format_arguments = {
        "subjectIdOrKey": _SERIALIZER.url("subject_id_or_key", subject_id_or_key, "str"),
    }

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

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

    return HttpRequest(method="DELETE", url=_url, headers=_headers, **kwargs)


def build_query_portal_meter_request(
    meter_slug: str,
    *,
    from_parameter: Optional[datetime.datetime] = None,
    to: Optional[datetime.datetime] = None,
    window_size: Optional[str] = None,
    window_time_zone: str = "UTC",
    group_by: Optional[List[str]] = None,
    **kwargs: Any
) -> HttpRequest:
    _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {})
    _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

    accept = _headers.pop("Accept", "application/json, text/csv, application/problem+json")

    # Construct URL
    _url = "/api/v1/portal/meters/{meterSlug}/query"
    path_format_arguments = {
        "meterSlug": _SERIALIZER.url("meter_slug", meter_slug, "str"),
    }

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

    # Construct parameters
    if from_parameter is not None:
        _params["from"] = _SERIALIZER.query("from_parameter", from_parameter, "iso-8601")
    if to is not None:
        _params["to"] = _SERIALIZER.query("to", to, "iso-8601")
    if window_size is not None:
        _params["windowSize"] = _SERIALIZER.query("window_size", window_size, "str")
    if window_time_zone is not None:
        _params["windowTimeZone"] = _SERIALIZER.query("window_time_zone", window_time_zone, "str")
    if group_by is not None:
        _params["groupBy"] = _SERIALIZER.query("group_by", group_by, "[str]")

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

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


class ClientOperationsMixin(ClientMixinABC):
    @overload
    def ingest_events(  # pylint: disable=inconsistent-return-statements
        self, body: JSON, *, content_type: str = "application/cloudevents+json", **kwargs: Any
    ) -> None:
        """Ingest events.

        :param body: Required.
        :type body: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/cloudevents+json".
        :paramtype content_type: str
        :return: None
        :rtype: None
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # JSON input template you can fill out and use as your body input.
                body = {
                    "id": "str",  # Identifies the event. Required.
                    "source": "str",  # Identifies the context in which an event happened.
                      Required.
                    "specversion": "str",  # The version of the CloudEvents specification which
                      the event uses. Required.
                    "subject": "str",  # Describes the subject of the event in the context of the
                      event producer (identified by source). Required.
                    "type": "str",  # Describes the type of event related to the originating
                      occurrence. Required.
                    "data": {
                        "str": {}  # Optional. The event payload.
                    },
                    "datacontenttype": "str",  # Optional. Content type of the data value. Must
                      adhere to RFC 2046 format. "application/json"
                    "dataschema": "str",  # Optional. Identifies the schema that data adheres to.
                    "time": "2020-02-20 00:00:00"  # Optional. Timestamp of when the occurrence
                      happened. Must adhere to RFC 3339.
                }
        """

    @overload
    def ingest_events(  # pylint: disable=inconsistent-return-statements
        self, body: List[JSON], *, content_type: str = "application/cloudevents-batch+json", **kwargs: Any
    ) -> None:
        """Ingest events.

        :param body: Required.
        :type body: list[JSON]
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/cloudevents-batch+json".
        :paramtype content_type: str
        :return: None
        :rtype: None
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # JSON input template you can fill out and use as your body input.
                body = [
                    {
                        "id": "str",  # Identifies the event. Required.
                        "source": "str",  # Identifies the context in which an event
                          happened. Required.
                        "specversion": "str",  # The version of the CloudEvents specification
                          which the event uses. Required.
                        "subject": "str",  # Describes the subject of the event in the
                          context of the event producer (identified by source). Required.
                        "type": "str",  # Describes the type of event related to the
                          originating occurrence. Required.
                        "data": {
                            "str": {}  # Optional. The event payload.
                        },
                        "datacontenttype": "str",  # Optional. Content type of the data
                          value. Must adhere to RFC 2046 format. "application/json"
                        "dataschema": "str",  # Optional. Identifies the schema that data
                          adheres to.
                        "time": "2020-02-20 00:00:00"  # Optional. Timestamp of when the
                          occurrence happened. Must adhere to RFC 3339.
                    }
                ]
        """

    @distributed_trace
    def ingest_events(  # pylint: disable=inconsistent-return-statements
        self, body: Union[JSON, List[JSON]], **kwargs: Any
    ) -> None:
        """Ingest events.

        :param body: Is either a JSON type or a [JSON] type. Required.
        :type body: JSON or list[JSON]
        :keyword content_type: Body Parameter content-type. Known values are:
         'application/cloudevents+json', 'application/cloudevents-batch+json'. Default value is None.
        :paramtype content_type: str
        :return: None
        :rtype: None
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # JSON input template you can fill out and use as your body input.
                body = {
                    "id": "str",  # Identifies the event. Required.
                    "source": "str",  # Identifies the context in which an event happened.
                      Required.
                    "specversion": "str",  # The version of the CloudEvents specification which
                      the event uses. Required.
                    "subject": "str",  # Describes the subject of the event in the context of the
                      event producer (identified by source). Required.
                    "type": "str",  # Describes the type of event related to the originating
                      occurrence. Required.
                    "data": {
                        "str": {}  # Optional. The event payload.
                    },
                    "datacontenttype": "str",  # Optional. Content type of the data value. Must
                      adhere to RFC 2046 format. "application/json"
                    "dataschema": "str",  # Optional. Identifies the schema that data adheres to.
                    "time": "2020-02-20 00:00:00"  # Optional. Timestamp of when the occurrence
                      happened. Must adhere to RFC 3339.
                }
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
            400: HttpResponseError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

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

        _json = None
        if isinstance(body, MutableMapping):
            content_type = content_type or "application/cloudevents+json"
            _json = body
        elif isinstance(body, list):
            content_type = content_type or "application/cloudevents-batch+json"
            _json = body

        _request = build_ingest_events_request(
            content_type=content_type,
            json=_json,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [204]:
            if _stream:
                response.read()  # Load the body in memory and close the socket
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response)

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

    @distributed_trace
    def list_events(
        self,
        *,
        from_parameter: Optional[datetime.datetime] = None,
        to: Optional[datetime.datetime] = None,
        limit: Optional[int] = None,
        **kwargs: Any
    ) -> List[JSON]:
        """Retrieve latest raw events.

        :keyword from_parameter: Start date-time in RFC 3339 format.
         Inclusive. Default value is None.
        :paramtype from_parameter: ~datetime.datetime
        :keyword to: End date-time in RFC 3339 format.
         Inclusive. Default value is None.
        :paramtype to: ~datetime.datetime
        :keyword limit: Number of events to return. Default value is None.
        :paramtype limit: int
        :return: list of JSON object
        :rtype: list[JSON]
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # response body for status code(s): 200
                response == [
                    {
                        "event": {
                            "id": "str",  # Identifies the event. Required.
                            "source": "str",  # Identifies the context in which an event
                              happened. Required.
                            "specversion": "str",  # The version of the CloudEvents
                              specification which the event uses. Required.
                            "subject": "str",  # Describes the subject of the event in
                              the context of the event producer (identified by source). Required.
                            "type": "str",  # Describes the type of event related to the
                              originating occurrence. Required.
                            "data": {
                                "str": {}  # Optional. The event payload.
                            },
                            "datacontenttype": "str",  # Optional. Content type of the
                              data value. Must adhere to RFC 2046 format. "application/json"
                            "dataschema": "str",  # Optional. Identifies the schema that
                              data adheres to.
                            "time": "2020-02-20 00:00:00"  # Optional. Timestamp of when
                              the occurrence happened. Must adhere to RFC 3339.
                        },
                        "validationError": "str"  # Optional.
                    }
                ]
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
            400: HttpResponseError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        cls: ClsType[List[JSON]] = kwargs.pop("cls", None)

        _request = build_list_events_request(
            from_parameter=from_parameter,
            to=to,
            limit=limit,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

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

        if response.content:
            deserialized = response.json()
        else:
            deserialized = None

        if cls:
            return cls(pipeline_response, cast(List[JSON], deserialized), {})  # type: ignore

        return cast(List[JSON], deserialized)  # type: ignore

    @distributed_trace
    def list_meters(self, **kwargs: Any) -> List[JSON]:
        """List meters.

        :return: list of JSON object
        :rtype: list[JSON]
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # response body for status code(s): 200
                response == [
                    {
                        "aggregation": "str",  # The aggregation type to use for the meter.
                          Required. Known values are: "SUM", "COUNT", "AVG", "MIN", and "MAX".
                        "eventType": "str",  # The event type to aggregate. Required.
                        "slug": "str",  # A unique identifier for the meter. Required.
                        "windowSize": "str",  # Aggregation window size. Required. Known
                          values are: "MINUTE", "HOUR", and "DAY".
                        "description": "str",  # Optional. A description of the meter.
                        "groupBy": {
                            "str": "str"  # Optional. Named JSONPath expressions to
                              extract the group by values from the event data.
                        },
                        "id": "str",  # Optional. A unique identifier for the meter.
                        "valueProperty": "str"  # Optional. JSONPath expression to extract
                          the value from the event data.
                    }
                ]
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        cls: ClsType[List[JSON]] = kwargs.pop("cls", None)

        _request = build_list_meters_request(
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

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

        if response.content:
            deserialized = response.json()
        else:
            deserialized = None

        if cls:
            return cls(pipeline_response, cast(List[JSON], deserialized), {})  # type: ignore

        return cast(List[JSON], deserialized)  # type: ignore

    @overload
    def create_meter(self, body: JSON, *, content_type: str = "application/json", **kwargs: Any) -> JSON:
        """Create meter.

        :param body: Required.
        :type body: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: JSON object
        :rtype: JSON
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # JSON input template you can fill out and use as your body input.
                body = {
                    "aggregation": "str",  # The aggregation type to use for the meter. Required.
                      Known values are: "SUM", "COUNT", "AVG", "MIN", and "MAX".
                    "eventType": "str",  # The event type to aggregate. Required.
                    "slug": "str",  # A unique identifier for the meter. Required.
                    "windowSize": "str",  # Aggregation window size. Required. Known values are:
                      "MINUTE", "HOUR", and "DAY".
                    "description": "str",  # Optional. A description of the meter.
                    "groupBy": {
                        "str": "str"  # Optional. Named JSONPath expressions to extract the
                          group by values from the event data.
                    },
                    "id": "str",  # Optional. A unique identifier for the meter.
                    "valueProperty": "str"  # Optional. JSONPath expression to extract the value
                      from the event data.
                }

                # response body for status code(s): 201
                response == {
                    "aggregation": "str",  # The aggregation type to use for the meter. Required.
                      Known values are: "SUM", "COUNT", "AVG", "MIN", and "MAX".
                    "eventType": "str",  # The event type to aggregate. Required.
                    "slug": "str",  # A unique identifier for the meter. Required.
                    "windowSize": "str",  # Aggregation window size. Required. Known values are:
                      "MINUTE", "HOUR", and "DAY".
                    "description": "str",  # Optional. A description of the meter.
                    "groupBy": {
                        "str": "str"  # Optional. Named JSONPath expressions to extract the
                          group by values from the event data.
                    },
                    "id": "str",  # Optional. A unique identifier for the meter.
                    "valueProperty": "str"  # Optional. JSONPath expression to extract the value
                      from the event data.
                }
        """

    @overload
    def create_meter(self, body: IO, *, content_type: str = "application/json", **kwargs: Any) -> JSON:
        """Create meter.

        :param body: Required.
        :type body: IO
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: JSON object
        :rtype: JSON
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # response body for status code(s): 201
                response == {
                    "aggregation": "str",  # The aggregation type to use for the meter. Required.
                      Known values are: "SUM", "COUNT", "AVG", "MIN", and "MAX".
                    "eventType": "str",  # The event type to aggregate. Required.
                    "slug": "str",  # A unique identifier for the meter. Required.
                    "windowSize": "str",  # Aggregation window size. Required. Known values are:
                      "MINUTE", "HOUR", and "DAY".
                    "description": "str",  # Optional. A description of the meter.
                    "groupBy": {
                        "str": "str"  # Optional. Named JSONPath expressions to extract the
                          group by values from the event data.
                    },
                    "id": "str",  # Optional. A unique identifier for the meter.
                    "valueProperty": "str"  # Optional. JSONPath expression to extract the value
                      from the event data.
                }
        """

    @distributed_trace
    def create_meter(self, body: Union[JSON, IO], **kwargs: Any) -> JSON:
        """Create meter.

        :param body: Is either a JSON type or a IO type. Required.
        :type body: JSON or IO
        :keyword content_type: Body Parameter content-type. Known values are: 'application/json'.
         Default value is None.
        :paramtype content_type: str
        :return: JSON object
        :rtype: JSON
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # JSON input template you can fill out and use as your body input.
                body = {
                    "aggregation": "str",  # The aggregation type to use for the meter. Required.
                      Known values are: "SUM", "COUNT", "AVG", "MIN", and "MAX".
                    "eventType": "str",  # The event type to aggregate. Required.
                    "slug": "str",  # A unique identifier for the meter. Required.
                    "windowSize": "str",  # Aggregation window size. Required. Known values are:
                      "MINUTE", "HOUR", and "DAY".
                    "description": "str",  # Optional. A description of the meter.
                    "groupBy": {
                        "str": "str"  # Optional. Named JSONPath expressions to extract the
                          group by values from the event data.
                    },
                    "id": "str",  # Optional. A unique identifier for the meter.
                    "valueProperty": "str"  # Optional. JSONPath expression to extract the value
                      from the event data.
                }

                # response body for status code(s): 201
                response == {
                    "aggregation": "str",  # The aggregation type to use for the meter. Required.
                      Known values are: "SUM", "COUNT", "AVG", "MIN", and "MAX".
                    "eventType": "str",  # The event type to aggregate. Required.
                    "slug": "str",  # A unique identifier for the meter. Required.
                    "windowSize": "str",  # Aggregation window size. Required. Known values are:
                      "MINUTE", "HOUR", and "DAY".
                    "description": "str",  # Optional. A description of the meter.
                    "groupBy": {
                        "str": "str"  # Optional. Named JSONPath expressions to extract the
                          group by values from the event data.
                    },
                    "id": "str",  # Optional. A unique identifier for the meter.
                    "valueProperty": "str"  # Optional. JSONPath expression to extract the value
                      from the event data.
                }
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
            400: HttpResponseError,
            501: HttpResponseError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

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

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

        _request = build_create_meter_request(
            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 = self._client._pipeline.run(  # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [201]:
            if _stream:
                response.read()  # Load the body in memory and close the socket
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response)

        if response.content:
            deserialized = response.json()
        else:
            deserialized = None

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

        return cast(JSON, deserialized)  # type: ignore

    @distributed_trace
    def get_meter(self, meter_id_or_slug: str, **kwargs: Any) -> JSON:
        """Get meter by slugs.

        :param meter_id_or_slug: A unique identifier for the meter. Required.
        :type meter_id_or_slug: str
        :return: JSON object
        :rtype: JSON
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # response body for status code(s): 200
                response == {
                    "aggregation": "str",  # The aggregation type to use for the meter. Required.
                      Known values are: "SUM", "COUNT", "AVG", "MIN", and "MAX".
                    "eventType": "str",  # The event type to aggregate. Required.
                    "slug": "str",  # A unique identifier for the meter. Required.
                    "windowSize": "str",  # Aggregation window size. Required. Known values are:
                      "MINUTE", "HOUR", and "DAY".
                    "description": "str",  # Optional. A description of the meter.
                    "groupBy": {
                        "str": "str"  # Optional. Named JSONPath expressions to extract the
                          group by values from the event data.
                    },
                    "id": "str",  # Optional. A unique identifier for the meter.
                    "valueProperty": "str"  # Optional. JSONPath expression to extract the value
                      from the event data.
                }
        """
        error_map = {
            401: ClientAuthenticationError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
            404: lambda response: ResourceNotFoundError(response=response),
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

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

        _request = build_get_meter_request(
            meter_id_or_slug=meter_id_or_slug,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

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

        if response.content:
            deserialized = response.json()
        else:
            deserialized = None

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

        return cast(JSON, deserialized)  # type: ignore

    @distributed_trace
    def delete_meter(  # pylint: disable=inconsistent-return-statements
        self, meter_id_or_slug: str, **kwargs: Any
    ) -> None:
        """Delete meter by slug.

        :param meter_id_or_slug: A unique identifier for the meter. Required.
        :type meter_id_or_slug: str
        :return: None
        :rtype: None
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map = {
            401: ClientAuthenticationError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
            404: lambda response: ResourceNotFoundError(response=response),
            501: HttpResponseError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

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

        _request = build_delete_meter_request(
            meter_id_or_slug=meter_id_or_slug,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [204]:
            if _stream:
                response.read()  # Load the body in memory and close the socket
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response)

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

    @distributed_trace
    def query_meter(
        self,
        meter_id_or_slug: str,
        *,
        from_parameter: Optional[datetime.datetime] = None,
        to: Optional[datetime.datetime] = None,
        window_size: Optional[str] = None,
        window_time_zone: str = "UTC",
        subject: Optional[List[str]] = None,
        group_by: Optional[List[str]] = None,
        **kwargs: Any
    ) -> Union[JSON, str]:
        """Query meter.

        :param meter_id_or_slug: A unique identifier for the meter. Required.
        :type meter_id_or_slug: str
        :keyword from_parameter: Start date-time in RFC 3339 format.
         Inclusive. Default value is None.
        :paramtype from_parameter: ~datetime.datetime
        :keyword to: End date-time in RFC 3339 format.
         Inclusive. Default value is None.
        :paramtype to: ~datetime.datetime
        :keyword window_size: If not specified, a single usage aggregate will be returned for the
         entirety of the specified period for each subject and group. Known values are: "MINUTE",
         "HOUR", and "DAY". Default value is None.
        :paramtype window_size: str
        :keyword window_time_zone: The value is the name of the time zone as defined in the IANA Time
         Zone Database (http://www.iana.org/time-zones).
         If not specified, the UTC timezone will be used. Default value is "UTC".
        :paramtype window_time_zone: str
        :keyword subject: Default value is None.
        :paramtype subject: list[str]
        :keyword group_by: If not specified a single aggregate will be returned for each subject and
         time window.
         ``subject`` is a reserved group by value. Default value is None.
        :paramtype group_by: list[str]
        :return: JSON object or str
        :rtype: JSON or str
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # response body for status code(s): 200
                response == {
                    "data": [
                        {
                            "value": 0.0,  # Required.
                            "windowEnd": "2020-02-20 00:00:00",  # Required.
                            "windowStart": "2020-02-20 00:00:00",  # Required.
                            "groupBy": {
                                "str": "str"  # Optional. Dictionary of
                                  :code:`<string>`.
                            },
                            "subject": "str"  # Optional. The subject of the meter value.
                        }
                    ],
                    "from": "2020-02-20 00:00:00",  # Optional.
                    "to": "2020-02-20 00:00:00",  # Optional.
                    "windowSize": "str"  # Optional. Aggregation window size. Known values are:
                      "MINUTE", "HOUR", and "DAY".
                }
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
            400: HttpResponseError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        cls: ClsType[Union[JSON, str]] = kwargs.pop("cls", None)

        _request = build_query_meter_request(
            meter_id_or_slug=meter_id_or_slug,
            from_parameter=from_parameter,
            to=to,
            window_size=window_size,
            window_time_zone=window_time_zone,
            subject=subject,
            group_by=group_by,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

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

        if response.status_code == 200:
            if response.content:
                deserialized = response.json()
            else:
                deserialized = None

        if response.status_code == 200:
            if response.content:
                deserialized = response.json()
            else:
                deserialized = None

        if cls:
            return cls(pipeline_response, cast(Union[JSON, str], deserialized), {})  # type: ignore

        return cast(Union[JSON, str], deserialized)  # type: ignore

    @distributed_trace
    def list_meter_subjects(self, meter_id_or_slug: str, **kwargs: Any) -> List[str]:
        """List meter subjects.

        :param meter_id_or_slug: A unique identifier for the meter. Required.
        :type meter_id_or_slug: str
        :return: list of str
        :rtype: list[str]
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # response body for status code(s): 200
                response == [
                    "str"  # Optional.
                ]
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
            400: HttpResponseError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        cls: ClsType[List[str]] = kwargs.pop("cls", None)

        _request = build_list_meter_subjects_request(
            meter_id_or_slug=meter_id_or_slug,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

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

        if response.content:
            deserialized = response.json()
        else:
            deserialized = None

        if cls:
            return cls(pipeline_response, cast(List[str], deserialized), {})  # type: ignore

        return cast(List[str], deserialized)  # type: ignore

    @overload
    def create_portal_token(
        self, body: Optional[JSON] = None, *, content_type: str = "application/json", **kwargs: Any
    ) -> JSON:
        """create_portal_token.

        :param body: Default value is None.
        :type body: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: JSON object
        :rtype: JSON
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # JSON input template you can fill out and use as your body input.
                body = {
                    "createdAt": "2020-02-20 00:00:00",  # Required.
                    "expiresAt": "2020-02-20 00:00:00",  # Required.
                    "id": "str",  # Required.
                    "subject": "str",  # Required.
                    "allowedMeterSlugs": [
                        "str"  # Optional. Optional, if defined only the specified meters
                          will be allowed.
                    ],
                    "expired": bool,  # Optional.
                    "token": "str"  # Optional. The token is only returned at creation.
                }

                # response body for status code(s): 200
                response == {
                    "createdAt": "2020-02-20 00:00:00",  # Required.
                    "expiresAt": "2020-02-20 00:00:00",  # Required.
                    "id": "str",  # Required.
                    "subject": "str",  # Required.
                    "allowedMeterSlugs": [
                        "str"  # Optional. Optional, if defined only the specified meters
                          will be allowed.
                    ],
                    "expired": bool,  # Optional.
                    "token": "str"  # Optional. The token is only returned at creation.
                }
        """

    @overload
    def create_portal_token(
        self, body: Optional[IO] = None, *, content_type: str = "application/json", **kwargs: Any
    ) -> JSON:
        """create_portal_token.

        :param body: Default value is None.
        :type body: IO
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: JSON object
        :rtype: JSON
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # response body for status code(s): 200
                response == {
                    "createdAt": "2020-02-20 00:00:00",  # Required.
                    "expiresAt": "2020-02-20 00:00:00",  # Required.
                    "id": "str",  # Required.
                    "subject": "str",  # Required.
                    "allowedMeterSlugs": [
                        "str"  # Optional. Optional, if defined only the specified meters
                          will be allowed.
                    ],
                    "expired": bool,  # Optional.
                    "token": "str"  # Optional. The token is only returned at creation.
                }
        """

    @distributed_trace
    def create_portal_token(self, body: Optional[Union[JSON, IO]] = None, **kwargs: Any) -> JSON:
        """create_portal_token.

        :param body: Is either a JSON type or a IO type. Default value is None.
        :type body: JSON or IO
        :keyword content_type: Body Parameter content-type. Known values are: 'application/json'.
         Default value is None.
        :paramtype content_type: str
        :return: JSON object
        :rtype: JSON
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # JSON input template you can fill out and use as your body input.
                body = {
                    "createdAt": "2020-02-20 00:00:00",  # Required.
                    "expiresAt": "2020-02-20 00:00:00",  # Required.
                    "id": "str",  # Required.
                    "subject": "str",  # Required.
                    "allowedMeterSlugs": [
                        "str"  # Optional. Optional, if defined only the specified meters
                          will be allowed.
                    ],
                    "expired": bool,  # Optional.
                    "token": "str"  # Optional. The token is only returned at creation.
                }

                # response body for status code(s): 200
                response == {
                    "createdAt": "2020-02-20 00:00:00",  # Required.
                    "expiresAt": "2020-02-20 00:00:00",  # Required.
                    "id": "str",  # Required.
                    "subject": "str",  # Required.
                    "allowedMeterSlugs": [
                        "str"  # Optional. Optional, if defined only the specified meters
                          will be allowed.
                    ],
                    "expired": bool,  # Optional.
                    "token": "str"  # Optional. The token is only returned at creation.
                }
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
            400: HttpResponseError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

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

        content_type = content_type or "application/json"
        _json = None
        _content = None
        if isinstance(body, (IOBase, bytes)):
            _content = body
        else:
            if body is not None:
                _json = body
            else:
                _json = None

        _request = build_create_portal_token_request(
            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 = self._client._pipeline.run(  # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

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

        if response.content:
            deserialized = response.json()
        else:
            deserialized = None

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

        return cast(JSON, deserialized)  # type: ignore

    @distributed_trace
    def list_portal_tokens(self, *, limit: int = 25, **kwargs: Any) -> List[JSON]:
        """list_portal_tokens.

        :keyword limit: Number of portal tokens to return. Default is 25. Default value is 25.
        :paramtype limit: int
        :return: list of JSON object
        :rtype: list[JSON]
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # response body for status code(s): 200
                response == [
                    {
                        "createdAt": "2020-02-20 00:00:00",  # Required.
                        "expiresAt": "2020-02-20 00:00:00",  # Required.
                        "id": "str",  # Required.
                        "subject": "str",  # Required.
                        "allowedMeterSlugs": [
                            "str"  # Optional. Optional, if defined only the specified
                              meters will be allowed.
                        ],
                        "expired": bool,  # Optional.
                        "token": "str"  # Optional. The token is only returned at creation.
                    }
                ]
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
            400: HttpResponseError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        cls: ClsType[List[JSON]] = kwargs.pop("cls", None)

        _request = build_list_portal_tokens_request(
            limit=limit,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

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

        if response.content:
            deserialized = response.json()
        else:
            deserialized = None

        if cls:
            return cls(pipeline_response, cast(List[JSON], deserialized), {})  # type: ignore

        return cast(List[JSON], deserialized)  # type: ignore

    @overload
    def invalidate_portal_tokens(  # pylint: disable=inconsistent-return-statements
        self, body: Optional[JSON] = None, *, content_type: str = "application/json", **kwargs: Any
    ) -> None:
        """invalidate_portal_tokens.

        :param body: Default value is None.
        :type body: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: None
        :rtype: None
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # JSON input template you can fill out and use as your body input.
                body = {
                    "id": "str",  # Optional. Optional portal token ID to invalidate one token
                      by.
                    "subject": "str"  # Optional. Optional subject to invalidate all tokens for
                      subject.
                }
        """

    @overload
    def invalidate_portal_tokens(  # pylint: disable=inconsistent-return-statements
        self, body: Optional[IO] = None, *, content_type: str = "application/json", **kwargs: Any
    ) -> None:
        """invalidate_portal_tokens.

        :param body: Default value is None.
        :type body: IO
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: None
        :rtype: None
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace
    def invalidate_portal_tokens(  # pylint: disable=inconsistent-return-statements
        self, body: Optional[Union[JSON, IO]] = None, **kwargs: Any
    ) -> None:
        """invalidate_portal_tokens.

        :param body: Is either a JSON type or a IO type. Default value is None.
        :type body: JSON or IO
        :keyword content_type: Body Parameter content-type. Known values are: 'application/json'.
         Default value is None.
        :paramtype content_type: str
        :return: None
        :rtype: None
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # JSON input template you can fill out and use as your body input.
                body = {
                    "id": "str",  # Optional. Optional portal token ID to invalidate one token
                      by.
                    "subject": "str"  # Optional. Optional subject to invalidate all tokens for
                      subject.
                }
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
            400: HttpResponseError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

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

        content_type = content_type or "application/json"
        _json = None
        _content = None
        if isinstance(body, (IOBase, bytes)):
            _content = body
        else:
            if body is not None:
                _json = body
            else:
                _json = None

        _request = build_invalidate_portal_tokens_request(
            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 = self._client._pipeline.run(  # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

        if response.status_code not in [204]:
            if _stream:
                response.read()  # Load the body in memory and close the socket
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response)

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

    @distributed_trace
    def list_subjects(self, **kwargs: Any) -> List[JSON]:
        """list_subjects.

        :return: list of JSON object
        :rtype: list[JSON]
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # response body for status code(s): 200
                response == [
                    {
                        "id": "str",  # Required.
                        "key": "str",  # Required.
                        "currentPeriodEnd": "2020-02-20 00:00:00",  # Optional.
                        "currentPeriodStart": "2020-02-20 00:00:00",  # Optional.
                        "displayName": "str",  # Optional.
                        "metadata": {
                            "str": {}  # Optional. Dictionary of :code:`<any>`.
                        },
                        "stripeCustomerId": "str"  # Optional.
                    }
                ]
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        cls: ClsType[List[JSON]] = kwargs.pop("cls", None)

        _request = build_list_subjects_request(
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

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

        if response.content:
            deserialized = response.json()
        else:
            deserialized = None

        if cls:
            return cls(pipeline_response, cast(List[JSON], deserialized), {})  # type: ignore

        return cast(List[JSON], deserialized)  # type: ignore

    @overload
    def upsert_subject(
        self, body: Optional[JSON] = None, *, content_type: str = "application/json", **kwargs: Any
    ) -> JSON:
        """Upserts a subject. Creates or updates subject.
        If the subject doesn't exist, it will be created.
        If the subject exists, it will be partially updated with the provided fields.

        :param body: Default value is None.
        :type body: JSON
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: JSON object
        :rtype: JSON
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # JSON input template you can fill out and use as your body input.
                body = {
                    "id": "str",  # Required.
                    "key": "str",  # Required.
                    "currentPeriodEnd": "2020-02-20 00:00:00",  # Optional.
                    "currentPeriodStart": "2020-02-20 00:00:00",  # Optional.
                    "displayName": "str",  # Optional.
                    "metadata": {
                        "str": {}  # Optional. Dictionary of :code:`<any>`.
                    },
                    "stripeCustomerId": "str"  # Optional.
                }

                # response body for status code(s): 200
                response == {
                    "id": "str",  # Required.
                    "key": "str",  # Required.
                    "currentPeriodEnd": "2020-02-20 00:00:00",  # Optional.
                    "currentPeriodStart": "2020-02-20 00:00:00",  # Optional.
                    "displayName": "str",  # Optional.
                    "metadata": {
                        "str": {}  # Optional. Dictionary of :code:`<any>`.
                    },
                    "stripeCustomerId": "str"  # Optional.
                }
        """

    @overload
    def upsert_subject(
        self, body: Optional[IO] = None, *, content_type: str = "application/json", **kwargs: Any
    ) -> JSON:
        """Upserts a subject. Creates or updates subject.
        If the subject doesn't exist, it will be created.
        If the subject exists, it will be partially updated with the provided fields.

        :param body: Default value is None.
        :type body: IO
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :return: JSON object
        :rtype: JSON
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # response body for status code(s): 200
                response == {
                    "id": "str",  # Required.
                    "key": "str",  # Required.
                    "currentPeriodEnd": "2020-02-20 00:00:00",  # Optional.
                    "currentPeriodStart": "2020-02-20 00:00:00",  # Optional.
                    "displayName": "str",  # Optional.
                    "metadata": {
                        "str": {}  # Optional. Dictionary of :code:`<any>`.
                    },
                    "stripeCustomerId": "str"  # Optional.
                }
        """

    @distributed_trace
    def upsert_subject(self, body: Optional[Union[JSON, IO]] = None, **kwargs: Any) -> JSON:
        """Upserts a subject. Creates or updates subject.
        If the subject doesn't exist, it will be created.
        If the subject exists, it will be partially updated with the provided fields.

        :param body: Is either a JSON type or a IO type. Default value is None.
        :type body: JSON or IO
        :keyword content_type: Body Parameter content-type. Known values are: 'application/json'.
         Default value is None.
        :paramtype content_type: str
        :return: JSON object
        :rtype: JSON
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # JSON input template you can fill out and use as your body input.
                body = {
                    "id": "str",  # Required.
                    "key": "str",  # Required.
                    "currentPeriodEnd": "2020-02-20 00:00:00",  # Optional.
                    "currentPeriodStart": "2020-02-20 00:00:00",  # Optional.
                    "displayName": "str",  # Optional.
                    "metadata": {
                        "str": {}  # Optional. Dictionary of :code:`<any>`.
                    },
                    "stripeCustomerId": "str"  # Optional.
                }

                # response body for status code(s): 200
                response == {
                    "id": "str",  # Required.
                    "key": "str",  # Required.
                    "currentPeriodEnd": "2020-02-20 00:00:00",  # Optional.
                    "currentPeriodStart": "2020-02-20 00:00:00",  # Optional.
                    "displayName": "str",  # Optional.
                    "metadata": {
                        "str": {}  # Optional. Dictionary of :code:`<any>`.
                    },
                    "stripeCustomerId": "str"  # Optional.
                }
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
            400: HttpResponseError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

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

        content_type = content_type or "application/json"
        _json = None
        _content = None
        if isinstance(body, (IOBase, bytes)):
            _content = body
        else:
            if body is not None:
                _json = body
            else:
                _json = None

        _request = build_upsert_subject_request(
            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 = self._client._pipeline.run(  # pylint: disable=protected-access
            _request, stream=_stream, **kwargs
        )

        response = pipeline_response.http_response

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

        if response.content:
            deserialized = response.json()
        else:
            deserialized = None

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

        return cast(JSON, deserialized)  # type: ignore

    @distributed_trace
    def get_subject(self, subject_id_or_key: str, **kwargs: Any) -> JSON:
        """get_subject.

        :param subject_id_or_key: A unique identifier for a subject. Required.
        :type subject_id_or_key: str
        :return: JSON object
        :rtype: JSON
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # response body for status code(s): 200
                response == {
                    "id": "str",  # Required.
                    "key": "str",  # Required.
                    "currentPeriodEnd": "2020-02-20 00:00:00",  # Optional.
                    "currentPeriodStart": "2020-02-20 00:00:00",  # Optional.
                    "displayName": "str",  # Optional.
                    "metadata": {
                        "str": {}  # Optional. Dictionary of :code:`<any>`.
                    },
                    "stripeCustomerId": "str"  # Optional.
                }
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

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

        _request = build_get_subject_request(
            subject_id_or_key=subject_id_or_key,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

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

        if response.content:
            deserialized = response.json()
        else:
            deserialized = None

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

        return cast(JSON, deserialized)  # type: ignore

    @distributed_trace
    def delete_subject(  # pylint: disable=inconsistent-return-statements
        self, subject_id_or_key: str, **kwargs: Any
    ) -> None:
        """delete_subject.

        :param subject_id_or_key: A unique identifier for a subject. Required.
        :type subject_id_or_key: str
        :return: None
        :rtype: None
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
            400: HttpResponseError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

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

        _request = build_delete_subject_request(
            subject_id_or_key=subject_id_or_key,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

        if response.status_code not in [204]:
            if _stream:
                response.read()  # Load the body in memory and close the socket
            map_error(status_code=response.status_code, response=response, error_map=error_map)
            raise HttpResponseError(response=response)

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

    @distributed_trace
    def query_portal_meter(
        self,
        meter_slug: str,
        *,
        from_parameter: Optional[datetime.datetime] = None,
        to: Optional[datetime.datetime] = None,
        window_size: Optional[str] = None,
        window_time_zone: str = "UTC",
        group_by: Optional[List[str]] = None,
        **kwargs: Any
    ) -> Union[JSON, str]:
        """query_portal_meter.

        :param meter_slug: Required.
        :type meter_slug: str
        :keyword from_parameter: Start date-time in RFC 3339 format.
         Inclusive. Default value is None.
        :paramtype from_parameter: ~datetime.datetime
        :keyword to: End date-time in RFC 3339 format.
         Inclusive. Default value is None.
        :paramtype to: ~datetime.datetime
        :keyword window_size: If not specified, a single usage aggregate will be returned for the
         entirety of the specified period for each subject and group. Known values are: "MINUTE",
         "HOUR", and "DAY". Default value is None.
        :paramtype window_size: str
        :keyword window_time_zone: The value is the name of the time zone as defined in the IANA Time
         Zone Database (http://www.iana.org/time-zones).
         If not specified, the UTC timezone will be used. Default value is "UTC".
        :paramtype window_time_zone: str
        :keyword group_by: If not specified a single aggregate will be returned for each subject and
         time window.
         ``subject`` is a reserved group by value. Default value is None.
        :paramtype group_by: list[str]
        :return: JSON object or str
        :rtype: JSON or str
        :raises ~azure.core.exceptions.HttpResponseError:

        Example:
            .. code-block:: python

                # response body for status code(s): 200
                response == {
                    "data": [
                        {
                            "value": 0.0,  # Required.
                            "windowEnd": "2020-02-20 00:00:00",  # Required.
                            "windowStart": "2020-02-20 00:00:00",  # Required.
                            "groupBy": {
                                "str": "str"  # Optional. Dictionary of
                                  :code:`<string>`.
                            },
                            "subject": "str"  # Optional. The subject of the meter value.
                        }
                    ],
                    "from": "2020-02-20 00:00:00",  # Optional.
                    "to": "2020-02-20 00:00:00",  # Optional.
                    "windowSize": "str"  # Optional. Aggregation window size. Known values are:
                      "MINUTE", "HOUR", and "DAY".
                }
                # response body for status code(s): 401
                response == {
                    "detail": "str",  # A human-readable explanation specific to this occurrence
                      of the problem. Required.
                    "status": 0,  # The HTTP status code generated by the origin server for this
                      occurrence of the problem. Required.
                    "title": "str",  # A a short, human-readable summary of the problem type.
                      Required.
                    "type": "str",  # Type contains a URI that identifies the problem type.
                      Required.
                    "instance": "str"  # Optional. A URI reference that identifies the specific
                      occurrence of the problem.
                }
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
            400: HttpResponseError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        cls: ClsType[Union[JSON, str]] = kwargs.pop("cls", None)

        _request = build_query_portal_meter_request(
            meter_slug=meter_slug,
            from_parameter=from_parameter,
            to=to,
            window_size=window_size,
            window_time_zone=window_time_zone,
            group_by=group_by,
            headers=_headers,
            params=_params,
        )
        _request.url = self._client.format_url(_request.url)

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

        response = pipeline_response.http_response

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

        if response.status_code == 200:
            if response.content:
                deserialized = response.json()
            else:
                deserialized = None

        if response.status_code == 200:
            if response.content:
                deserialized = response.json()
            else:
                deserialized = None

        if response.status_code == 401:
            if response.content:
                deserialized = response.json()
            else:
                deserialized = None

        if cls:
            return cls(pipeline_response, cast(Union[JSON, str], deserialized), {})  # type: ignore

        return cast(Union[JSON, str], deserialized)  # type: ignore
