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

from __future__ import annotations

import typing

from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ...core.request_options import RequestOptions
from ...types.delete_env_response import DeleteEnvResponse
from ...types.env_list_response import EnvListResponse
from ...types.env_response import EnvResponse
from ...types.resolve_env_response import ResolveEnvResponse
from .raw_client import AsyncRawEnvironmentsClient, RawEnvironmentsClient

if typing.TYPE_CHECKING:
    from .branches.client import AsyncBranchesClient, BranchesClient
    from .secrets.client import AsyncSecretsClient, SecretsClient
# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class EnvironmentsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawEnvironmentsClient(client_wrapper=client_wrapper)
        self._client_wrapper = client_wrapper
        self._branches: typing.Optional[BranchesClient] = None
        self._secrets: typing.Optional[SecretsClient] = None

    @property
    def with_raw_response(self) -> RawEnvironmentsClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        RawEnvironmentsClient
        """
        return self._raw_client

    def list(
        self, namespace_slug: str, agent_name: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        EnvListResponse
            Successful Response

        Examples
        --------
        from terminaluse import TerminalUseBase

        client = TerminalUseBase(
            agent_api_key="YOUR_AGENT_API_KEY",
            token="YOUR_TOKEN",
            base_url="https://yourhost.com/path/to/api",
        )
        client.agents.environments.list(
            namespace_slug="namespace_slug",
            agent_name="agent_name",
        )
        """
        _response = self._raw_client.list(namespace_slug, agent_name, request_options=request_options)
        return _response.data

    def create(
        self,
        namespace_slug: str,
        agent_name: str,
        *,
        branch_rules: typing.Sequence[str],
        name: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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
        -------
        EnvResponse
            Successful Response

        Examples
        --------
        from terminaluse import TerminalUseBase

        client = TerminalUseBase(
            agent_api_key="YOUR_AGENT_API_KEY",
            token="YOUR_TOKEN",
            base_url="https://yourhost.com/path/to/api",
        )
        client.agents.environments.create(
            namespace_slug="namespace_slug",
            agent_name="agent_name",
            branch_rules=["branch_rules"],
            name="name",
        )
        """
        _response = self._raw_client.create(
            namespace_slug, agent_name, branch_rules=branch_rules, name=name, request_options=request_options
        )
        return _response.data

    def retrieve(
        self,
        namespace_slug: str,
        agent_name: str,
        env_name: str,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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
        -------
        EnvResponse
            Successful Response

        Examples
        --------
        from terminaluse import TerminalUseBase

        client = TerminalUseBase(
            agent_api_key="YOUR_AGENT_API_KEY",
            token="YOUR_TOKEN",
            base_url="https://yourhost.com/path/to/api",
        )
        client.agents.environments.retrieve(
            namespace_slug="namespace_slug",
            agent_name="agent_name",
            env_name="env_name",
        )
        """
        _response = self._raw_client.retrieve(namespace_slug, agent_name, env_name, request_options=request_options)
        return _response.data

    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,
    ) -> 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
        -------
        EnvResponse
            Successful Response

        Examples
        --------
        from terminaluse import TerminalUseBase

        client = TerminalUseBase(
            agent_api_key="YOUR_AGENT_API_KEY",
            token="YOUR_TOKEN",
            base_url="https://yourhost.com/path/to/api",
        )
        client.agents.environments.update(
            namespace_slug="namespace_slug",
            agent_name="agent_name",
            env_name="env_name",
        )
        """
        _response = self._raw_client.update(
            namespace_slug, agent_name, env_name, branch_rules=branch_rules, request_options=request_options
        )
        return _response.data

    def delete(
        self,
        namespace_slug: str,
        agent_name: str,
        env_name: str,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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
        -------
        DeleteEnvResponse
            Successful Response

        Examples
        --------
        from terminaluse import TerminalUseBase

        client = TerminalUseBase(
            agent_api_key="YOUR_AGENT_API_KEY",
            token="YOUR_TOKEN",
            base_url="https://yourhost.com/path/to/api",
        )
        client.agents.environments.delete(
            namespace_slug="namespace_slug",
            agent_name="agent_name",
            env_name="env_name",
        )
        """
        _response = self._raw_client.delete(namespace_slug, agent_name, env_name, request_options=request_options)
        return _response.data

    def resolve_env(
        self,
        namespace_slug: str,
        agent_name: str,
        *,
        branch: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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
        -------
        ResolveEnvResponse
            Successful Response

        Examples
        --------
        from terminaluse import TerminalUseBase

        client = TerminalUseBase(
            agent_api_key="YOUR_AGENT_API_KEY",
            token="YOUR_TOKEN",
            base_url="https://yourhost.com/path/to/api",
        )
        client.agents.environments.resolve_env(
            namespace_slug="namespace_slug",
            agent_name="agent_name",
            branch="branch",
        )
        """
        _response = self._raw_client.resolve_env(
            namespace_slug, agent_name, branch=branch, request_options=request_options
        )
        return _response.data

    @property
    def branches(self):
        if self._branches is None:
            from .branches.client import BranchesClient  # noqa: E402

            self._branches = BranchesClient(client_wrapper=self._client_wrapper)
        return self._branches

    @property
    def secrets(self):
        if self._secrets is None:
            from .secrets.client import SecretsClient  # noqa: E402

            self._secrets = SecretsClient(client_wrapper=self._client_wrapper)
        return self._secrets


class AsyncEnvironmentsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawEnvironmentsClient(client_wrapper=client_wrapper)
        self._client_wrapper = client_wrapper
        self._branches: typing.Optional[AsyncBranchesClient] = None
        self._secrets: typing.Optional[AsyncSecretsClient] = None

    @property
    def with_raw_response(self) -> AsyncRawEnvironmentsClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        AsyncRawEnvironmentsClient
        """
        return self._raw_client

    async def list(
        self, namespace_slug: str, agent_name: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> 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
        -------
        EnvListResponse
            Successful Response

        Examples
        --------
        import asyncio

        from terminaluse import AsyncTerminalUseBase

        client = AsyncTerminalUseBase(
            agent_api_key="YOUR_AGENT_API_KEY",
            token="YOUR_TOKEN",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.agents.environments.list(
                namespace_slug="namespace_slug",
                agent_name="agent_name",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.list(namespace_slug, agent_name, request_options=request_options)
        return _response.data

    async def create(
        self,
        namespace_slug: str,
        agent_name: str,
        *,
        branch_rules: typing.Sequence[str],
        name: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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
        -------
        EnvResponse
            Successful Response

        Examples
        --------
        import asyncio

        from terminaluse import AsyncTerminalUseBase

        client = AsyncTerminalUseBase(
            agent_api_key="YOUR_AGENT_API_KEY",
            token="YOUR_TOKEN",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.agents.environments.create(
                namespace_slug="namespace_slug",
                agent_name="agent_name",
                branch_rules=["branch_rules"],
                name="name",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.create(
            namespace_slug, agent_name, branch_rules=branch_rules, name=name, request_options=request_options
        )
        return _response.data

    async def retrieve(
        self,
        namespace_slug: str,
        agent_name: str,
        env_name: str,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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
        -------
        EnvResponse
            Successful Response

        Examples
        --------
        import asyncio

        from terminaluse import AsyncTerminalUseBase

        client = AsyncTerminalUseBase(
            agent_api_key="YOUR_AGENT_API_KEY",
            token="YOUR_TOKEN",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.agents.environments.retrieve(
                namespace_slug="namespace_slug",
                agent_name="agent_name",
                env_name="env_name",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.retrieve(
            namespace_slug, agent_name, env_name, request_options=request_options
        )
        return _response.data

    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,
    ) -> 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
        -------
        EnvResponse
            Successful Response

        Examples
        --------
        import asyncio

        from terminaluse import AsyncTerminalUseBase

        client = AsyncTerminalUseBase(
            agent_api_key="YOUR_AGENT_API_KEY",
            token="YOUR_TOKEN",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.agents.environments.update(
                namespace_slug="namespace_slug",
                agent_name="agent_name",
                env_name="env_name",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.update(
            namespace_slug, agent_name, env_name, branch_rules=branch_rules, request_options=request_options
        )
        return _response.data

    async def delete(
        self,
        namespace_slug: str,
        agent_name: str,
        env_name: str,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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
        -------
        DeleteEnvResponse
            Successful Response

        Examples
        --------
        import asyncio

        from terminaluse import AsyncTerminalUseBase

        client = AsyncTerminalUseBase(
            agent_api_key="YOUR_AGENT_API_KEY",
            token="YOUR_TOKEN",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.agents.environments.delete(
                namespace_slug="namespace_slug",
                agent_name="agent_name",
                env_name="env_name",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.delete(namespace_slug, agent_name, env_name, request_options=request_options)
        return _response.data

    async def resolve_env(
        self,
        namespace_slug: str,
        agent_name: str,
        *,
        branch: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> 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
        -------
        ResolveEnvResponse
            Successful Response

        Examples
        --------
        import asyncio

        from terminaluse import AsyncTerminalUseBase

        client = AsyncTerminalUseBase(
            agent_api_key="YOUR_AGENT_API_KEY",
            token="YOUR_TOKEN",
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.agents.environments.resolve_env(
                namespace_slug="namespace_slug",
                agent_name="agent_name",
                branch="branch",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.resolve_env(
            namespace_slug, agent_name, branch=branch, request_options=request_options
        )
        return _response.data

    @property
    def branches(self):
        if self._branches is None:
            from .branches.client import AsyncBranchesClient  # noqa: E402

            self._branches = AsyncBranchesClient(client_wrapper=self._client_wrapper)
        return self._branches

    @property
    def secrets(self):
        if self._secrets is None:
            from .secrets.client import AsyncSecretsClient  # noqa: E402

            self._secrets = AsyncSecretsClient(client_wrapper=self._client_wrapper)
        return self._secrets
