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

from azure.core.async_paging import AsyncItemPaged, AsyncList
from azure.core.exceptions import (
    ClientAuthenticationError,
    HttpResponseError,
    ResourceExistsError,
    ResourceNotFoundError,
    ResourceNotModifiedError,
    map_error,
)
from azure.core.pipeline import PipelineResponse
from azure.core.pipeline.transport import AsyncHttpResponse
from azure.core.rest import HttpRequest
from azure.core.tracing.decorator import distributed_trace
from azure.core.tracing.decorator_async import distributed_trace_async
from azure.core.utils import case_insensitive_dict
from azure.mgmt.core.exceptions import ARMErrorFormat

from ... import models as _models
from ..._vendor import _convert_request
from ...operations._labs_operations import (
    build_create_or_update_request,
    build_delete_request,
    build_generate_invite_code_request,
    build_get_request,
    build_list_all_request,
    build_list_request,
)
from .._vendor import EducationManagementClientMixinABC

if sys.version_info >= (3, 8):
    from typing import Literal  # pylint: disable=no-name-in-module, ungrouped-imports
else:
    from typing_extensions import Literal  # type: ignore  # pylint: disable=ungrouped-imports
T = TypeVar("T")
ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]]


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

        Instead, you should access the following operations through
        :class:`~azure.mgmt.education.aio.EducationManagementClient`'s
        :attr:`labs` attribute.
    """

    models = _models

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

    @distributed_trace
    def list_all(
        self,
        billing_account_name: str,
        billing_profile_name: str,
        include_budget: Optional[bool] = None,
        include_deleted: Optional[bool] = None,
        **kwargs: Any
    ) -> AsyncIterable["_models.LabDetails"]:
        """Get a list of labs associated with the provided billing account name and billing profile name.

        :param billing_account_name: Billing account name. Required.
        :type billing_account_name: str
        :param billing_profile_name: Billing profile name. Required.
        :type billing_profile_name: str
        :param include_budget: May be used to include budget information. Default value is None.
        :type include_budget: bool
        :param include_deleted: May be used to show deleted items. Default value is None.
        :type include_deleted: bool
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: An iterator like instance of either LabDetails or the result of cls(response)
        :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.education.models.LabDetails]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: Literal["2021-12-01-preview"] = kwargs.pop(
            "api_version", _params.pop("api-version", self._config.api_version)
        )
        cls: ClsType[_models.LabListResult] = kwargs.pop("cls", None)

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

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

                request = build_list_all_request(
                    billing_account_name=billing_account_name,
                    billing_profile_name=billing_profile_name,
                    include_budget=include_budget,
                    include_deleted=include_deleted,
                    api_version=api_version,
                    template_url=self.list_all.metadata["url"],
                    headers=_headers,
                    params=_params,
                )
                request = _convert_request(request)
                request.url = self._client.format_url(request.url)

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

        async def extract_data(pipeline_response):
            deserialized = self._deserialize("LabListResult", pipeline_response)
            list_of_elem = deserialized.value
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.next_link or None, AsyncList(list_of_elem)

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

            pipeline_response: PipelineResponse = await self._client._pipeline.run(  # pylint: disable=protected-access
                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)
                error = self._deserialize.failsafe_deserialize(_models.ErrorResponseBody, pipeline_response)
                raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)

    list_all.metadata = {
        "url": "/providers/Microsoft.Billing/billingAccounts/{billingAccountName}/billingProfiles/{billingProfileName}/providers/Microsoft.Education/labs"
    }

    @distributed_trace
    def list(
        self,
        billing_account_name: str,
        billing_profile_name: str,
        invoice_section_name: str,
        include_budget: Optional[bool] = None,
        **kwargs: Any
    ) -> AsyncIterable["_models.LabDetails"]:
        """Get the details for a specific lab associated with the provided billing account name, billing
        profile name, and invoice section name.

        :param billing_account_name: Billing account name. Required.
        :type billing_account_name: str
        :param billing_profile_name: Billing profile name. Required.
        :type billing_profile_name: str
        :param invoice_section_name: Invoice section name. Required.
        :type invoice_section_name: str
        :param include_budget: May be used to include budget information. Default value is None.
        :type include_budget: bool
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: An iterator like instance of either LabDetails or the result of cls(response)
        :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.mgmt.education.models.LabDetails]
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        _headers = kwargs.pop("headers", {}) or {}
        _params = case_insensitive_dict(kwargs.pop("params", {}) or {})

        api_version: Literal["2021-12-01-preview"] = kwargs.pop(
            "api_version", _params.pop("api-version", self._config.api_version)
        )
        cls: ClsType[_models.LabListResult] = kwargs.pop("cls", None)

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

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

                request = build_list_request(
                    billing_account_name=billing_account_name,
                    billing_profile_name=billing_profile_name,
                    invoice_section_name=invoice_section_name,
                    include_budget=include_budget,
                    api_version=api_version,
                    template_url=self.list.metadata["url"],
                    headers=_headers,
                    params=_params,
                )
                request = _convert_request(request)
                request.url = self._client.format_url(request.url)

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

        async def extract_data(pipeline_response):
            deserialized = self._deserialize("LabListResult", pipeline_response)
            list_of_elem = deserialized.value
            if cls:
                list_of_elem = cls(list_of_elem)  # type: ignore
            return deserialized.next_link or None, AsyncList(list_of_elem)

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

            pipeline_response: PipelineResponse = await self._client._pipeline.run(  # pylint: disable=protected-access
                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)
                error = self._deserialize.failsafe_deserialize(_models.ErrorResponseBody, pipeline_response)
                raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat)

            return pipeline_response

        return AsyncItemPaged(get_next, extract_data)

    list.metadata = {
        "url": "/providers/Microsoft.Billing/billingAccounts/{billingAccountName}/billingProfiles/{billingProfileName}/invoiceSections/{invoiceSectionName}/providers/Microsoft.Education/labs"
    }

    @distributed_trace_async
    async def get(
        self,
        billing_account_name: str,
        billing_profile_name: str,
        invoice_section_name: str,
        include_budget: Optional[bool] = None,
        **kwargs: Any
    ) -> _models.LabDetails:
        """Get the details for a specific lab associated with the provided billing account name, billing
        profile name, and invoice section name.

        :param billing_account_name: Billing account name. Required.
        :type billing_account_name: str
        :param billing_profile_name: Billing profile name. Required.
        :type billing_profile_name: str
        :param invoice_section_name: Invoice section name. Required.
        :type invoice_section_name: str
        :param include_budget: May be used to include budget information. Default value is None.
        :type include_budget: bool
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: LabDetails or the result of cls(response)
        :rtype: ~azure.mgmt.education.models.LabDetails
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: Literal["2021-12-01-preview"] = kwargs.pop(
            "api_version", _params.pop("api-version", self._config.api_version)
        )
        cls: ClsType[_models.LabDetails] = kwargs.pop("cls", None)

        request = build_get_request(
            billing_account_name=billing_account_name,
            billing_profile_name=billing_profile_name,
            invoice_section_name=invoice_section_name,
            include_budget=include_budget,
            api_version=api_version,
            template_url=self.get.metadata["url"],
            headers=_headers,
            params=_params,
        )
        request = _convert_request(request)
        request.url = self._client.format_url(request.url)

        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # pylint: disable=protected-access
            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)
            error = self._deserialize.failsafe_deserialize(_models.ErrorResponseBody, pipeline_response)
            raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat)

        deserialized = self._deserialize("LabDetails", pipeline_response)

        if cls:
            return cls(pipeline_response, deserialized, {})

        return deserialized

    get.metadata = {
        "url": "/providers/Microsoft.Billing/billingAccounts/{billingAccountName}/billingProfiles/{billingProfileName}/invoiceSections/{invoiceSectionName}/providers/Microsoft.Education/labs/default"
    }

    @distributed_trace_async
    async def delete(  # pylint: disable=inconsistent-return-statements
        self, billing_account_name: str, billing_profile_name: str, invoice_section_name: str, **kwargs: Any
    ) -> None:
        """Delete a specific lab associated with the provided billing account name, billing profile name,
        and invoice section name. Note all students must be removed from the lab in order to delete the
        lab.

        :param billing_account_name: Billing account name. Required.
        :type billing_account_name: str
        :param billing_profile_name: Billing profile name. Required.
        :type billing_profile_name: str
        :param invoice_section_name: Invoice section name. Required.
        :type invoice_section_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:
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: Literal["2021-12-01-preview"] = kwargs.pop(
            "api_version", _params.pop("api-version", self._config.api_version)
        )
        cls: ClsType[None] = kwargs.pop("cls", None)

        request = build_delete_request(
            billing_account_name=billing_account_name,
            billing_profile_name=billing_profile_name,
            invoice_section_name=invoice_section_name,
            api_version=api_version,
            template_url=self.delete.metadata["url"],
            headers=_headers,
            params=_params,
        )
        request = _convert_request(request)
        request.url = self._client.format_url(request.url)

        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # pylint: disable=protected-access
            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)
            error = self._deserialize.failsafe_deserialize(_models.ErrorResponseBody, pipeline_response)
            raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat)

        if cls:
            return cls(pipeline_response, None, {})

    delete.metadata = {
        "url": "/providers/Microsoft.Billing/billingAccounts/{billingAccountName}/billingProfiles/{billingProfileName}/invoiceSections/{invoiceSectionName}/providers/Microsoft.Education/labs/default"
    }

    @overload
    async def create_or_update(
        self,
        billing_account_name: str,
        billing_profile_name: str,
        invoice_section_name: str,
        parameters: _models.LabDetails,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.LabDetails:
        """Create a new lab or update a previously created lab.

        :param billing_account_name: Billing account name. Required.
        :type billing_account_name: str
        :param billing_profile_name: Billing profile name. Required.
        :type billing_profile_name: str
        :param invoice_section_name: Invoice section name. Required.
        :type invoice_section_name: str
        :param parameters: Request parameters that are provided to create lab resource. Required.
        :type parameters: ~azure.mgmt.education.models.LabDetails
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: LabDetails or the result of cls(response)
        :rtype: ~azure.mgmt.education.models.LabDetails
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def create_or_update(
        self,
        billing_account_name: str,
        billing_profile_name: str,
        invoice_section_name: str,
        parameters: IO,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.LabDetails:
        """Create a new lab or update a previously created lab.

        :param billing_account_name: Billing account name. Required.
        :type billing_account_name: str
        :param billing_profile_name: Billing profile name. Required.
        :type billing_profile_name: str
        :param invoice_section_name: Invoice section name. Required.
        :type invoice_section_name: str
        :param parameters: Request parameters that are provided to create lab resource. Required.
        :type parameters: IO
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: LabDetails or the result of cls(response)
        :rtype: ~azure.mgmt.education.models.LabDetails
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def create_or_update(
        self,
        billing_account_name: str,
        billing_profile_name: str,
        invoice_section_name: str,
        parameters: Union[_models.LabDetails, IO],
        **kwargs: Any
    ) -> _models.LabDetails:
        """Create a new lab or update a previously created lab.

        :param billing_account_name: Billing account name. Required.
        :type billing_account_name: str
        :param billing_profile_name: Billing profile name. Required.
        :type billing_profile_name: str
        :param invoice_section_name: Invoice section name. Required.
        :type invoice_section_name: str
        :param parameters: Request parameters that are provided to create lab resource. Is either a
         model type or a IO type. Required.
        :type parameters: ~azure.mgmt.education.models.LabDetails or IO
        :keyword content_type: Body Parameter content-type. Known values are: 'application/json'.
         Default value is None.
        :paramtype content_type: str
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: LabDetails or the result of cls(response)
        :rtype: ~azure.mgmt.education.models.LabDetails
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: Literal["2021-12-01-preview"] = kwargs.pop(
            "api_version", _params.pop("api-version", self._config.api_version)
        )
        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.LabDetails] = kwargs.pop("cls", None)

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

        request = build_create_or_update_request(
            billing_account_name=billing_account_name,
            billing_profile_name=billing_profile_name,
            invoice_section_name=invoice_section_name,
            api_version=api_version,
            content_type=content_type,
            json=_json,
            content=_content,
            template_url=self.create_or_update.metadata["url"],
            headers=_headers,
            params=_params,
        )
        request = _convert_request(request)
        request.url = self._client.format_url(request.url)

        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # pylint: disable=protected-access
            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)
            error = self._deserialize.failsafe_deserialize(_models.ErrorResponseBody, pipeline_response)
            raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat)

        if response.status_code == 200:
            deserialized = self._deserialize("LabDetails", pipeline_response)

        if response.status_code == 201:
            deserialized = self._deserialize("LabDetails", pipeline_response)

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

        return deserialized  # type: ignore

    create_or_update.metadata = {
        "url": "/providers/Microsoft.Billing/billingAccounts/{billingAccountName}/billingProfiles/{billingProfileName}/invoiceSections/{invoiceSectionName}/providers/Microsoft.Education/labs/default"
    }

    @overload
    async def generate_invite_code(
        self,
        billing_account_name: str,
        billing_profile_name: str,
        invoice_section_name: str,
        parameters: _models.InviteCodeGenerateRequest,
        only_update_student_count_parameter: Optional[bool] = None,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.LabDetails:
        """Generate invite code for a lab.

        :param billing_account_name: Billing account name. Required.
        :type billing_account_name: str
        :param billing_profile_name: Billing profile name. Required.
        :type billing_profile_name: str
        :param invoice_section_name: Invoice section name. Required.
        :type invoice_section_name: str
        :param parameters: Request parameters that are provided to generate invite code. Required.
        :type parameters: ~azure.mgmt.education.models.InviteCodeGenerateRequest
        :param only_update_student_count_parameter: set this flag to true if you want to update student
         count without generating a new invite code. Default value is None.
        :type only_update_student_count_parameter: bool
        :keyword content_type: Body Parameter content-type. Content type parameter for JSON body.
         Default value is "application/json".
        :paramtype content_type: str
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: LabDetails or the result of cls(response)
        :rtype: ~azure.mgmt.education.models.LabDetails
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @overload
    async def generate_invite_code(
        self,
        billing_account_name: str,
        billing_profile_name: str,
        invoice_section_name: str,
        parameters: IO,
        only_update_student_count_parameter: Optional[bool] = None,
        *,
        content_type: str = "application/json",
        **kwargs: Any
    ) -> _models.LabDetails:
        """Generate invite code for a lab.

        :param billing_account_name: Billing account name. Required.
        :type billing_account_name: str
        :param billing_profile_name: Billing profile name. Required.
        :type billing_profile_name: str
        :param invoice_section_name: Invoice section name. Required.
        :type invoice_section_name: str
        :param parameters: Request parameters that are provided to generate invite code. Required.
        :type parameters: IO
        :param only_update_student_count_parameter: set this flag to true if you want to update student
         count without generating a new invite code. Default value is None.
        :type only_update_student_count_parameter: bool
        :keyword content_type: Body Parameter content-type. Content type parameter for binary body.
         Default value is "application/json".
        :paramtype content_type: str
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: LabDetails or the result of cls(response)
        :rtype: ~azure.mgmt.education.models.LabDetails
        :raises ~azure.core.exceptions.HttpResponseError:
        """

    @distributed_trace_async
    async def generate_invite_code(
        self,
        billing_account_name: str,
        billing_profile_name: str,
        invoice_section_name: str,
        parameters: Union[_models.InviteCodeGenerateRequest, IO],
        only_update_student_count_parameter: Optional[bool] = None,
        **kwargs: Any
    ) -> _models.LabDetails:
        """Generate invite code for a lab.

        :param billing_account_name: Billing account name. Required.
        :type billing_account_name: str
        :param billing_profile_name: Billing profile name. Required.
        :type billing_profile_name: str
        :param invoice_section_name: Invoice section name. Required.
        :type invoice_section_name: str
        :param parameters: Request parameters that are provided to generate invite code. Is either a
         model type or a IO type. Required.
        :type parameters: ~azure.mgmt.education.models.InviteCodeGenerateRequest or IO
        :param only_update_student_count_parameter: set this flag to true if you want to update student
         count without generating a new invite code. Default value is None.
        :type only_update_student_count_parameter: bool
        :keyword content_type: Body Parameter content-type. Known values are: 'application/json'.
         Default value is None.
        :paramtype content_type: str
        :keyword callable cls: A custom type or function that will be passed the direct response
        :return: LabDetails or the result of cls(response)
        :rtype: ~azure.mgmt.education.models.LabDetails
        :raises ~azure.core.exceptions.HttpResponseError:
        """
        error_map = {
            401: ClientAuthenticationError,
            404: ResourceNotFoundError,
            409: ResourceExistsError,
            304: ResourceNotModifiedError,
        }
        error_map.update(kwargs.pop("error_map", {}) or {})

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

        api_version: Literal["2021-12-01-preview"] = kwargs.pop(
            "api_version", _params.pop("api-version", self._config.api_version)
        )
        content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None))
        cls: ClsType[_models.LabDetails] = kwargs.pop("cls", None)

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

        request = build_generate_invite_code_request(
            billing_account_name=billing_account_name,
            billing_profile_name=billing_profile_name,
            invoice_section_name=invoice_section_name,
            only_update_student_count_parameter=only_update_student_count_parameter,
            api_version=api_version,
            content_type=content_type,
            json=_json,
            content=_content,
            template_url=self.generate_invite_code.metadata["url"],
            headers=_headers,
            params=_params,
        )
        request = _convert_request(request)
        request.url = self._client.format_url(request.url)

        pipeline_response: PipelineResponse = await self._client._pipeline.run(  # pylint: disable=protected-access
            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)
            error = self._deserialize.failsafe_deserialize(_models.ErrorResponseBody, pipeline_response)
            raise HttpResponseError(response=response, model=error, error_format=ARMErrorFormat)

        deserialized = self._deserialize("LabDetails", pipeline_response)

        if cls:
            return cls(pipeline_response, deserialized, {})

        return deserialized

    generate_invite_code.metadata = {
        "url": "/providers/Microsoft.Billing/billingAccounts/{billingAccountName}/billingProfiles/{billingProfileName}/invoiceSections/{invoiceSectionName}/providers/Microsoft.Education/labs/default/generateInviteCode"
    }
