# 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.delete_env_response import DeleteEnvResponse
from ...types.env_list_response import EnvListResponse
from ...types.env_response import EnvResponse
from ...types.http_validation_error import HttpValidationError
from ...types.resolve_env_response import ResolveEnvResponse

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


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

    def list(
        self, namespace_slug: str, agent_name: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[EnvListResponse]:
        """
        List all environments for an agent.

            Environments define deployment targets (e.g., production, staging, preview).

        Parameters
        ----------
        namespace_slug : str

        agent_name : str

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

        Returns
        -------
        HttpResponse[EnvListResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"agents/{jsonable_encoder(namespace_slug)}/{jsonable_encoder(agent_name)}/environments",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    EnvListResponse,
                    parse_obj_as(
                        type_=EnvListResponse,  # 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(
        self,
        namespace_slug: str,
        agent_name: str,
        *,
        branch_rules: typing.Sequence[str],
        name: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[EnvResponse]:
        """
        Create a new environment for an agent.

            Environments define deployment targets with branch matching rules.
            The is_prod flag cannot be set via API - production environment is protected.

            **Branch Rules:**
            - Exact match: ["main"] or ["develop"]
            - Wildcard: ["feature/*"] matches feature/foo, feature/bar
            - Catch-all: ["*"] matches any branch

        Parameters
        ----------
        namespace_slug : str

        agent_name : str

        branch_rules : typing.Sequence[str]
            Branch patterns for matching (e.g., ['feature/*'], ['develop'])

        name : str
            Environment name (lowercase alphanumeric and hyphens only)

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

        Returns
        -------
        HttpResponse[EnvResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"agents/{jsonable_encoder(namespace_slug)}/{jsonable_encoder(agent_name)}/environments",
            method="POST",
            json={
                "branch_rules": branch_rules,
                "name": name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    EnvResponse,
                    parse_obj_as(
                        type_=EnvResponse,  # 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 retrieve(
        self,
        namespace_slug: str,
        agent_name: str,
        env_name: str,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[EnvResponse]:
        """
        Get environment details by name.

        Parameters
        ----------
        namespace_slug : str

        agent_name : str

        env_name : str

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

        Returns
        -------
        HttpResponse[EnvResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"agents/{jsonable_encoder(namespace_slug)}/{jsonable_encoder(agent_name)}/environments/{jsonable_encoder(env_name)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    EnvResponse,
                    parse_obj_as(
                        type_=EnvResponse,  # 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(
        self,
        namespace_slug: str,
        agent_name: str,
        env_name: str,
        *,
        branch_rules: typing.Optional[typing.Sequence[str]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[EnvResponse]:
        """
        Update an existing environment.

            All fields are optional - only provided fields will be updated.

            **Production Environment Constraints:**
            - branch_rules must be exactly one literal string (no wildcards)
            - is_prod cannot be changed via API

        Parameters
        ----------
        namespace_slug : str

        agent_name : str

        env_name : str

        branch_rules : typing.Optional[typing.Sequence[str]]
            Branch patterns for matching

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

        Returns
        -------
        HttpResponse[EnvResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"agents/{jsonable_encoder(namespace_slug)}/{jsonable_encoder(agent_name)}/environments/{jsonable_encoder(env_name)}",
            method="PUT",
            json={
                "branch_rules": branch_rules,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    EnvResponse,
                    parse_obj_as(
                        type_=EnvResponse,  # 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 delete(
        self,
        namespace_slug: str,
        agent_name: str,
        env_name: str,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[DeleteEnvResponse]:
        """
        Delete an environment.

            **Note:** Production environments (is_prod=True) cannot be deleted.

        Parameters
        ----------
        namespace_slug : str

        agent_name : str

        env_name : str

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

        Returns
        -------
        HttpResponse[DeleteEnvResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"agents/{jsonable_encoder(namespace_slug)}/{jsonable_encoder(agent_name)}/environments/{jsonable_encoder(env_name)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteEnvResponse,
                    parse_obj_as(
                        type_=DeleteEnvResponse,  # 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 resolve_env(
        self,
        namespace_slug: str,
        agent_name: str,
        *,
        branch: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ResolveEnvResponse]:
        """
        Resolve which environment matches a given branch.

            Uses specificity-based matching:
            - Exact match wins over wildcards (e.g., "main" matches production before preview)
            - Prefix wildcards match by length (e.g., "feature/*" beats "*")
            - Catch-all "*" has lowest priority

            Returns 404 if no environment matches the branch.

        Parameters
        ----------
        namespace_slug : str

        agent_name : str

        branch : str

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

        Returns
        -------
        HttpResponse[ResolveEnvResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"agents/{jsonable_encoder(namespace_slug)}/{jsonable_encoder(agent_name)}/resolve-env",
            method="GET",
            params={
                "branch": branch,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ResolveEnvResponse,
                    parse_obj_as(
                        type_=ResolveEnvResponse,  # 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 AsyncRawEnvironmentsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list(
        self, namespace_slug: str, agent_name: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[EnvListResponse]:
        """
        List all environments for an agent.

            Environments define deployment targets (e.g., production, staging, preview).

        Parameters
        ----------
        namespace_slug : str

        agent_name : str

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

        Returns
        -------
        AsyncHttpResponse[EnvListResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"agents/{jsonable_encoder(namespace_slug)}/{jsonable_encoder(agent_name)}/environments",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    EnvListResponse,
                    parse_obj_as(
                        type_=EnvListResponse,  # 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(
        self,
        namespace_slug: str,
        agent_name: str,
        *,
        branch_rules: typing.Sequence[str],
        name: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[EnvResponse]:
        """
        Create a new environment for an agent.

            Environments define deployment targets with branch matching rules.
            The is_prod flag cannot be set via API - production environment is protected.

            **Branch Rules:**
            - Exact match: ["main"] or ["develop"]
            - Wildcard: ["feature/*"] matches feature/foo, feature/bar
            - Catch-all: ["*"] matches any branch

        Parameters
        ----------
        namespace_slug : str

        agent_name : str

        branch_rules : typing.Sequence[str]
            Branch patterns for matching (e.g., ['feature/*'], ['develop'])

        name : str
            Environment name (lowercase alphanumeric and hyphens only)

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

        Returns
        -------
        AsyncHttpResponse[EnvResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"agents/{jsonable_encoder(namespace_slug)}/{jsonable_encoder(agent_name)}/environments",
            method="POST",
            json={
                "branch_rules": branch_rules,
                "name": name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    EnvResponse,
                    parse_obj_as(
                        type_=EnvResponse,  # 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 retrieve(
        self,
        namespace_slug: str,
        agent_name: str,
        env_name: str,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[EnvResponse]:
        """
        Get environment details by name.

        Parameters
        ----------
        namespace_slug : str

        agent_name : str

        env_name : str

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

        Returns
        -------
        AsyncHttpResponse[EnvResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"agents/{jsonable_encoder(namespace_slug)}/{jsonable_encoder(agent_name)}/environments/{jsonable_encoder(env_name)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    EnvResponse,
                    parse_obj_as(
                        type_=EnvResponse,  # 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(
        self,
        namespace_slug: str,
        agent_name: str,
        env_name: str,
        *,
        branch_rules: typing.Optional[typing.Sequence[str]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[EnvResponse]:
        """
        Update an existing environment.

            All fields are optional - only provided fields will be updated.

            **Production Environment Constraints:**
            - branch_rules must be exactly one literal string (no wildcards)
            - is_prod cannot be changed via API

        Parameters
        ----------
        namespace_slug : str

        agent_name : str

        env_name : str

        branch_rules : typing.Optional[typing.Sequence[str]]
            Branch patterns for matching

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

        Returns
        -------
        AsyncHttpResponse[EnvResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"agents/{jsonable_encoder(namespace_slug)}/{jsonable_encoder(agent_name)}/environments/{jsonable_encoder(env_name)}",
            method="PUT",
            json={
                "branch_rules": branch_rules,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    EnvResponse,
                    parse_obj_as(
                        type_=EnvResponse,  # 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 delete(
        self,
        namespace_slug: str,
        agent_name: str,
        env_name: str,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[DeleteEnvResponse]:
        """
        Delete an environment.

            **Note:** Production environments (is_prod=True) cannot be deleted.

        Parameters
        ----------
        namespace_slug : str

        agent_name : str

        env_name : str

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

        Returns
        -------
        AsyncHttpResponse[DeleteEnvResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"agents/{jsonable_encoder(namespace_slug)}/{jsonable_encoder(agent_name)}/environments/{jsonable_encoder(env_name)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteEnvResponse,
                    parse_obj_as(
                        type_=DeleteEnvResponse,  # 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 resolve_env(
        self,
        namespace_slug: str,
        agent_name: str,
        *,
        branch: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ResolveEnvResponse]:
        """
        Resolve which environment matches a given branch.

            Uses specificity-based matching:
            - Exact match wins over wildcards (e.g., "main" matches production before preview)
            - Prefix wildcards match by length (e.g., "feature/*" beats "*")
            - Catch-all "*" has lowest priority

            Returns 404 if no environment matches the branch.

        Parameters
        ----------
        namespace_slug : str

        agent_name : str

        branch : str

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

        Returns
        -------
        AsyncHttpResponse[ResolveEnvResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"agents/{jsonable_encoder(namespace_slug)}/{jsonable_encoder(agent_name)}/resolve-env",
            method="GET",
            params={
                "branch": branch,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ResolveEnvResponse,
                    parse_obj_as(
                        type_=ResolveEnvResponse,  # 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)
