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

import typing

from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.request_options import RequestOptions
from ..types.delete_response import DeleteResponse
from ..types.project import Project
from ..types.project_collaborator_response import ProjectCollaboratorResponse
from ..types.project_collaborators_response import ProjectCollaboratorsResponse
from ..types.project_list_item import ProjectListItem
from .raw_client import AsyncRawProjectsClient, RawProjectsClient
from .types.upsert_project_collaborator_request_role import UpsertProjectCollaboratorRequestRole

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


class ProjectsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawProjectsClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        RawProjectsClient
        """
        return self._raw_client

    def list(
        self,
        *,
        namespace_id: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        page_number: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.List[ProjectListItem]:
        """
        List all projects the user has access to.

        Parameters
        ----------
        namespace_id : typing.Optional[str]
            Filter by namespace ID

        limit : typing.Optional[int]
            Maximum number of results

        page_number : typing.Optional[int]
            Page number

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

        Returns
        -------
        typing.List[ProjectListItem]
            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.projects.list()
        """
        _response = self._raw_client.list(
            namespace_id=namespace_id, limit=limit, page_number=page_number, request_options=request_options
        )
        return _response.data

    def create(
        self,
        *,
        name: str,
        namespace_id: str,
        description: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Project:
        """
        Create a new project within a namespace.

        Parameters
        ----------
        name : str
            Project name (unique within namespace).

        namespace_id : str
            The namespace this project belongs to.

        description : typing.Optional[str]
            Optional project description.

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

        Returns
        -------
        Project
            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.projects.create(
            name="name",
            namespace_id="namespace_id",
        )
        """
        _response = self._raw_client.create(
            name=name, namespace_id=namespace_id, description=description, request_options=request_options
        )
        return _response.data

    def retrieve(self, project_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Project:
        """
        Get a project by ID.

        Parameters
        ----------
        project_id : str

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

        Returns
        -------
        Project
            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.projects.retrieve(
            project_id="project_id",
        )
        """
        _response = self._raw_client.retrieve(project_id, request_options=request_options)
        return _response.data

    def delete(self, project_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> DeleteResponse:
        """
        Delete a project (must be empty).

        Parameters
        ----------
        project_id : str

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

        Returns
        -------
        DeleteResponse
            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.projects.delete(
            project_id="project_id",
        )
        """
        _response = self._raw_client.delete(project_id, request_options=request_options)
        return _response.data

    def update(
        self,
        project_id: str,
        *,
        description: typing.Optional[str] = OMIT,
        name: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Project:
        """
        Update a project's properties.

        Parameters
        ----------
        project_id : str

        description : typing.Optional[str]
            Optional project description.

        name : typing.Optional[str]
            Project name.

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

        Returns
        -------
        Project
            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.projects.update(
            project_id="project_id",
        )
        """
        _response = self._raw_client.update(
            project_id, description=description, name=name, request_options=request_options
        )
        return _response.data

    def list_collaborators(
        self, project_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> ProjectCollaboratorsResponse:
        """
        List explicit collaborator roles on a project.

        Parameters
        ----------
        project_id : str

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

        Returns
        -------
        ProjectCollaboratorsResponse
            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.projects.list_collaborators(
            project_id="project_id",
        )
        """
        _response = self._raw_client.list_collaborators(project_id, request_options=request_options)
        return _response.data

    def upsert_collaborator(
        self,
        project_id: str,
        member_id: str,
        *,
        role: UpsertProjectCollaboratorRequestRole,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ProjectCollaboratorResponse:
        """
        Create or update an explicit collaborator role on a project.

        Parameters
        ----------
        project_id : str

        member_id : str

        role : UpsertProjectCollaboratorRequestRole
            Role to assign.

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

        Returns
        -------
        ProjectCollaboratorResponse
            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.projects.upsert_collaborator(
            project_id="project_id",
            member_id="member_id",
            role="discoverer",
        )
        """
        _response = self._raw_client.upsert_collaborator(
            project_id, member_id, role=role, request_options=request_options
        )
        return _response.data

    def remove_collaborator(
        self, project_id: str, member_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> DeleteResponse:
        """
        Remove explicit collaborator role tuples from a project.

        Parameters
        ----------
        project_id : str

        member_id : str

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

        Returns
        -------
        DeleteResponse
            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.projects.remove_collaborator(
            project_id="project_id",
            member_id="member_id",
        )
        """
        _response = self._raw_client.remove_collaborator(project_id, member_id, request_options=request_options)
        return _response.data


class AsyncProjectsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawProjectsClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        AsyncRawProjectsClient
        """
        return self._raw_client

    async def list(
        self,
        *,
        namespace_id: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        page_number: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.List[ProjectListItem]:
        """
        List all projects the user has access to.

        Parameters
        ----------
        namespace_id : typing.Optional[str]
            Filter by namespace ID

        limit : typing.Optional[int]
            Maximum number of results

        page_number : typing.Optional[int]
            Page number

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

        Returns
        -------
        typing.List[ProjectListItem]
            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.projects.list()


        asyncio.run(main())
        """
        _response = await self._raw_client.list(
            namespace_id=namespace_id, limit=limit, page_number=page_number, request_options=request_options
        )
        return _response.data

    async def create(
        self,
        *,
        name: str,
        namespace_id: str,
        description: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Project:
        """
        Create a new project within a namespace.

        Parameters
        ----------
        name : str
            Project name (unique within namespace).

        namespace_id : str
            The namespace this project belongs to.

        description : typing.Optional[str]
            Optional project description.

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

        Returns
        -------
        Project
            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.projects.create(
                name="name",
                namespace_id="namespace_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.create(
            name=name, namespace_id=namespace_id, description=description, request_options=request_options
        )
        return _response.data

    async def retrieve(self, project_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Project:
        """
        Get a project by ID.

        Parameters
        ----------
        project_id : str

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

        Returns
        -------
        Project
            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.projects.retrieve(
                project_id="project_id",
            )


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

    async def delete(
        self, project_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> DeleteResponse:
        """
        Delete a project (must be empty).

        Parameters
        ----------
        project_id : str

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

        Returns
        -------
        DeleteResponse
            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.projects.delete(
                project_id="project_id",
            )


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

    async def update(
        self,
        project_id: str,
        *,
        description: typing.Optional[str] = OMIT,
        name: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Project:
        """
        Update a project's properties.

        Parameters
        ----------
        project_id : str

        description : typing.Optional[str]
            Optional project description.

        name : typing.Optional[str]
            Project name.

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

        Returns
        -------
        Project
            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.projects.update(
                project_id="project_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.update(
            project_id, description=description, name=name, request_options=request_options
        )
        return _response.data

    async def list_collaborators(
        self, project_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> ProjectCollaboratorsResponse:
        """
        List explicit collaborator roles on a project.

        Parameters
        ----------
        project_id : str

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

        Returns
        -------
        ProjectCollaboratorsResponse
            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.projects.list_collaborators(
                project_id="project_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.list_collaborators(project_id, request_options=request_options)
        return _response.data

    async def upsert_collaborator(
        self,
        project_id: str,
        member_id: str,
        *,
        role: UpsertProjectCollaboratorRequestRole,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ProjectCollaboratorResponse:
        """
        Create or update an explicit collaborator role on a project.

        Parameters
        ----------
        project_id : str

        member_id : str

        role : UpsertProjectCollaboratorRequestRole
            Role to assign.

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

        Returns
        -------
        ProjectCollaboratorResponse
            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.projects.upsert_collaborator(
                project_id="project_id",
                member_id="member_id",
                role="discoverer",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.upsert_collaborator(
            project_id, member_id, role=role, request_options=request_options
        )
        return _response.data

    async def remove_collaborator(
        self, project_id: str, member_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> DeleteResponse:
        """
        Remove explicit collaborator role tuples from a project.

        Parameters
        ----------
        project_id : str

        member_id : str

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

        Returns
        -------
        DeleteResponse
            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.projects.remove_collaborator(
                project_id="project_id",
                member_id="member_id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.remove_collaborator(project_id, member_id, request_options=request_options)
        return _response.data
