# This file was auto-generated by Fern from our API Definition.

import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.app import App
from ..types.app_variant_response import AppVariantResponse
from ..types.create_app_output import CreateAppOutput
from ..types.environment_output import EnvironmentOutput
from ..types.environment_output_extended import EnvironmentOutputExtended
from ..types.http_validation_error import HttpValidationError
from ..types.update_app_output import UpdateAppOutput

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class RawAppsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def list_app_variants(
        self, app_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.List[AppVariantResponse]]:
        """
        Retrieve a list of app variants for a given app ID.

        Args:
            app_id (str): The ID of the app to retrieve variants for.

        Returns:
            List[AppVariantResponse]: A list of app variants for the given app ID.

        Parameters
        ----------
        app_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.List[AppVariantResponse]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"apps/{jsonable_encoder(app_id)}/variants",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[AppVariantResponse],
                    parse_obj_as(
                        type_=typing.List[AppVariantResponse],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    def get_variant_by_env(
        self,
        *,
        app_id: str,
        environment: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[AppVariantResponse]:
        """
        Retrieve the app variant based on the provided app_id and environment.

        Args:
            app_id (str): The ID of the app to retrieve the variant for.
            environment (str): The environment of the app variant to retrieve.

        Raises:
            HTTPException: If the app variant is not found (status_code=500), or if a ValueError is raised (status_code=400), or if any other exception is raised (status_code=500).

        Returns:
            AppVariantResponse: The retrieved app variant.

        Parameters
        ----------
        app_id : str

        environment : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[AppVariantResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "apps/get_variant_by_env",
            method="GET",
            params={
                "app_id": app_id,
                "environment": environment,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AppVariantResponse,
                    parse_obj_as(
                        type_=AppVariantResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    def list_apps(
        self,
        *,
        app_name: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[typing.List[App]]:
        """
        Retrieve a list of apps filtered by app_name.

        Args:
            app_name (Optional[str]): The name of the app to filter by.

        Returns:
            List[App]: A list of apps filtered by app_name.

        Raises:
            HTTPException: If there was an error retrieving the list of apps.

        Parameters
        ----------
        app_name : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.List[App]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "apps",
            method="GET",
            params={
                "app_name": app_name,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[App],
                    parse_obj_as(
                        type_=typing.List[App],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    def create_app(
        self,
        *,
        app_name: str,
        template_key: typing.Optional[str] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        workspace_id: typing.Optional[str] = OMIT,
        organization_id: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[CreateAppOutput]:
        """
        Create a new app for a user or organization.

        Args:
            payload (CreateApp): The payload containing the app name and organization ID (optional).

        Returns:
            CreateAppOutput: The output containing the newly created app's ID and name.

        Raises:
            HTTPException: If there is an error creating the app or the user does not have permission to access the app.

        Parameters
        ----------
        app_name : str

        template_key : typing.Optional[str]

        project_id : typing.Optional[str]

        workspace_id : typing.Optional[str]

        organization_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[CreateAppOutput]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "apps",
            method="POST",
            json={
                "app_name": app_name,
                "template_key": template_key,
                "project_id": project_id,
                "workspace_id": workspace_id,
                "organization_id": organization_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateAppOutput,
                    parse_obj_as(
                        type_=CreateAppOutput,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    def remove_app(
        self, app_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.Optional[typing.Any]]:
        """
        Remove app, all its variant.

        Arguments:
            app -- App to remove

        Parameters
        ----------
        app_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.Optional[typing.Any]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"apps/{jsonable_encoder(app_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return HttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    def update_app(
        self,
        app_id: str,
        *,
        app_name: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[UpdateAppOutput]:
        """
        Update an app for a user or organization.

        Args:
            app_id (str): The ID of the app.
            payload (UpdateApp): The payload containing the app name.

        Returns:
            UpdateAppOutput: The output containing the newly created app's ID and name.

        Raises:
            HTTPException: If there is an error creating the app or the user does not have permission to access the app.

        Parameters
        ----------
        app_id : str

        app_name : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[UpdateAppOutput]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"apps/{jsonable_encoder(app_id)}",
            method="PATCH",
            json={
                "app_name": app_name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpdateAppOutput,
                    parse_obj_as(
                        type_=UpdateAppOutput,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    def add_variant_from_url(
        self,
        app_id: str,
        *,
        variant_name: str,
        url: str,
        commit_message: typing.Optional[str] = OMIT,
        base_name: typing.Optional[str] = OMIT,
        config_name: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[typing.Optional[typing.Any]]:
        """
        Parameters
        ----------
        app_id : str

        variant_name : str

        url : str

        commit_message : typing.Optional[str]

        base_name : typing.Optional[str]

        config_name : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.Optional[typing.Any]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"apps/{jsonable_encoder(app_id)}/variant/from-service",
            method="POST",
            json={
                "variant_name": variant_name,
                "url": url,
                "commit_message": commit_message,
                "base_name": base_name,
                "config_name": config_name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if _response is None or not _response.text.strip():
                return HttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    def add_variant_from_key(
        self,
        app_id: str,
        *,
        variant_name: str,
        key: str,
        commit_message: typing.Optional[str] = OMIT,
        base_name: typing.Optional[str] = OMIT,
        config_name: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[typing.Optional[typing.Any]]:
        """
        Parameters
        ----------
        app_id : str

        variant_name : str

        key : str

        commit_message : typing.Optional[str]

        base_name : typing.Optional[str]

        config_name : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.Optional[typing.Any]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"apps/{jsonable_encoder(app_id)}/variant/from-template",
            method="POST",
            json={
                "variant_name": variant_name,
                "key": key,
                "commit_message": commit_message,
                "base_name": base_name,
                "config_name": config_name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if _response is None or not _response.text.strip():
                return HttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    def list_environments(
        self, app_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.List[EnvironmentOutput]]:
        """
        Retrieve a list of environments for a given app ID.

        Args:
            app_id (str): The ID of the app to retrieve environments for.

        Returns:
            List[EnvironmentOutput]: A list of environment objects.

        Parameters
        ----------
        app_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.List[EnvironmentOutput]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"apps/{jsonable_encoder(app_id)}/environments",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[EnvironmentOutput],
                    parse_obj_as(
                        type_=typing.List[EnvironmentOutput],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    def environment_revisions(
        self,
        app_id: str,
        environment_name: typing.Optional[typing.Any],
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[EnvironmentOutputExtended]:
        """
        Parameters
        ----------
        app_id : str

        environment_name : typing.Optional[typing.Any]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[EnvironmentOutputExtended]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"apps/{jsonable_encoder(app_id)}/revisions/{jsonable_encoder(environment_name)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    EnvironmentOutputExtended,
                    parse_obj_as(
                        type_=EnvironmentOutputExtended,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )


class AsyncRawAppsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list_app_variants(
        self, app_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.List[AppVariantResponse]]:
        """
        Retrieve a list of app variants for a given app ID.

        Args:
            app_id (str): The ID of the app to retrieve variants for.

        Returns:
            List[AppVariantResponse]: A list of app variants for the given app ID.

        Parameters
        ----------
        app_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.List[AppVariantResponse]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"apps/{jsonable_encoder(app_id)}/variants",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[AppVariantResponse],
                    parse_obj_as(
                        type_=typing.List[AppVariantResponse],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    async def get_variant_by_env(
        self,
        *,
        app_id: str,
        environment: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[AppVariantResponse]:
        """
        Retrieve the app variant based on the provided app_id and environment.

        Args:
            app_id (str): The ID of the app to retrieve the variant for.
            environment (str): The environment of the app variant to retrieve.

        Raises:
            HTTPException: If the app variant is not found (status_code=500), or if a ValueError is raised (status_code=400), or if any other exception is raised (status_code=500).

        Returns:
            AppVariantResponse: The retrieved app variant.

        Parameters
        ----------
        app_id : str

        environment : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[AppVariantResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "apps/get_variant_by_env",
            method="GET",
            params={
                "app_id": app_id,
                "environment": environment,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AppVariantResponse,
                    parse_obj_as(
                        type_=AppVariantResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    async def list_apps(
        self,
        *,
        app_name: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[typing.List[App]]:
        """
        Retrieve a list of apps filtered by app_name.

        Args:
            app_name (Optional[str]): The name of the app to filter by.

        Returns:
            List[App]: A list of apps filtered by app_name.

        Raises:
            HTTPException: If there was an error retrieving the list of apps.

        Parameters
        ----------
        app_name : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.List[App]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "apps",
            method="GET",
            params={
                "app_name": app_name,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[App],
                    parse_obj_as(
                        type_=typing.List[App],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    async def create_app(
        self,
        *,
        app_name: str,
        template_key: typing.Optional[str] = OMIT,
        project_id: typing.Optional[str] = OMIT,
        workspace_id: typing.Optional[str] = OMIT,
        organization_id: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[CreateAppOutput]:
        """
        Create a new app for a user or organization.

        Args:
            payload (CreateApp): The payload containing the app name and organization ID (optional).

        Returns:
            CreateAppOutput: The output containing the newly created app's ID and name.

        Raises:
            HTTPException: If there is an error creating the app or the user does not have permission to access the app.

        Parameters
        ----------
        app_name : str

        template_key : typing.Optional[str]

        project_id : typing.Optional[str]

        workspace_id : typing.Optional[str]

        organization_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[CreateAppOutput]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "apps",
            method="POST",
            json={
                "app_name": app_name,
                "template_key": template_key,
                "project_id": project_id,
                "workspace_id": workspace_id,
                "organization_id": organization_id,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CreateAppOutput,
                    parse_obj_as(
                        type_=CreateAppOutput,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    async def remove_app(
        self, app_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.Optional[typing.Any]]:
        """
        Remove app, all its variant.

        Arguments:
            app -- App to remove

        Parameters
        ----------
        app_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.Optional[typing.Any]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"apps/{jsonable_encoder(app_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return AsyncHttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    async def update_app(
        self,
        app_id: str,
        *,
        app_name: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[UpdateAppOutput]:
        """
        Update an app for a user or organization.

        Args:
            app_id (str): The ID of the app.
            payload (UpdateApp): The payload containing the app name.

        Returns:
            UpdateAppOutput: The output containing the newly created app's ID and name.

        Raises:
            HTTPException: If there is an error creating the app or the user does not have permission to access the app.

        Parameters
        ----------
        app_id : str

        app_name : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[UpdateAppOutput]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"apps/{jsonable_encoder(app_id)}",
            method="PATCH",
            json={
                "app_name": app_name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    UpdateAppOutput,
                    parse_obj_as(
                        type_=UpdateAppOutput,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    async def add_variant_from_url(
        self,
        app_id: str,
        *,
        variant_name: str,
        url: str,
        commit_message: typing.Optional[str] = OMIT,
        base_name: typing.Optional[str] = OMIT,
        config_name: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[typing.Optional[typing.Any]]:
        """
        Parameters
        ----------
        app_id : str

        variant_name : str

        url : str

        commit_message : typing.Optional[str]

        base_name : typing.Optional[str]

        config_name : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.Optional[typing.Any]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"apps/{jsonable_encoder(app_id)}/variant/from-service",
            method="POST",
            json={
                "variant_name": variant_name,
                "url": url,
                "commit_message": commit_message,
                "base_name": base_name,
                "config_name": config_name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if _response is None or not _response.text.strip():
                return AsyncHttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    async def add_variant_from_key(
        self,
        app_id: str,
        *,
        variant_name: str,
        key: str,
        commit_message: typing.Optional[str] = OMIT,
        base_name: typing.Optional[str] = OMIT,
        config_name: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[typing.Optional[typing.Any]]:
        """
        Parameters
        ----------
        app_id : str

        variant_name : str

        key : str

        commit_message : typing.Optional[str]

        base_name : typing.Optional[str]

        config_name : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.Optional[typing.Any]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"apps/{jsonable_encoder(app_id)}/variant/from-template",
            method="POST",
            json={
                "variant_name": variant_name,
                "key": key,
                "commit_message": commit_message,
                "base_name": base_name,
                "config_name": config_name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if _response is None or not _response.text.strip():
                return AsyncHttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Optional[typing.Any],
                    parse_obj_as(
                        type_=typing.Optional[typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    async def list_environments(
        self, app_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.List[EnvironmentOutput]]:
        """
        Retrieve a list of environments for a given app ID.

        Args:
            app_id (str): The ID of the app to retrieve environments for.

        Returns:
            List[EnvironmentOutput]: A list of environment objects.

        Parameters
        ----------
        app_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.List[EnvironmentOutput]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"apps/{jsonable_encoder(app_id)}/environments",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[EnvironmentOutput],
                    parse_obj_as(
                        type_=typing.List[EnvironmentOutput],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )

    async def environment_revisions(
        self,
        app_id: str,
        environment_name: typing.Optional[typing.Any],
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[EnvironmentOutputExtended]:
        """
        Parameters
        ----------
        app_id : str

        environment_name : typing.Optional[typing.Any]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[EnvironmentOutputExtended]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"apps/{jsonable_encoder(app_id)}/revisions/{jsonable_encoder(environment_name)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    EnvironmentOutputExtended,
                    parse_obj_as(
                        type_=EnvironmentOutputExtended,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(
                status_code=_response.status_code,
                headers=dict(_response.headers),
                body=_response.text,
            )
        raise ApiError(
            status_code=_response.status_code,
            headers=dict(_response.headers),
            body=_response_json,
        )
