# This file is auto-generated by oagen. Do not edit.

from __future__ import annotations

from typing import TYPE_CHECKING, Any, Dict, Optional, Union

if TYPE_CHECKING:
    from .._client import AsyncWorkOSClient, WorkOSClient

from .._types import RequestOptions, enum_value, NOT_GIVEN, NotGiven
from workos.common.models.group import Group
from workos.common.models.user_organization_membership_base_list_data import (
    UserOrganizationMembershipBaseListData,
)
from workos.common.models.pagination_order import PaginationOrder
from .._pagination import AsyncPage, SyncPage


class Groups:
    """Groups API resources."""

    def __init__(self, client: "WorkOSClient") -> None:
        self._client = client

    def list_organization_groups(
        self,
        organization_id: str,
        *,
        limit: Optional[int] = None,
        before: Optional[str] = None,
        after: Optional[str] = None,
        order: Optional[Union[PaginationOrder, str]] = "desc",
        request_options: Optional[RequestOptions] = None,
    ) -> SyncPage[Group]:
        """List groups

        Get a paginated list of groups within an organization.

        Args:
            organization_id: The ID of the organization.
            limit: Upper limit on the number of objects to return, between `1` and `100`. Defaults to `10`.
            before: An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `before="obj_123"` to fetch a new batch of objects before `"obj_123"`.
            after: An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `after="obj_123"` to fetch a new batch of objects after `"obj_123"`.
            order: Order the results by the creation time. Supported values are `"asc"` (ascending), `"desc"` (descending), and `"normal"` (descending with reversed cursor semantics where `before` fetches older records and `after` fetches newer records). Defaults to `desc`.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            SyncPage[Group]

        Raises:
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        params = {
            k: v
            for k, v in {
                "limit": limit,
                "before": before,
                "after": after,
                "order": enum_value(order) if order is not None else None,
            }.items()
            if v is not None
        }
        return self._client.request_page(
            method="get",
            path=("organizations", str(organization_id), "groups"),
            model=Group,
            params=params,
            request_options=request_options,
        )

    def create_organization_group(
        self,
        organization_id: str,
        *,
        name: str,
        description: Union[str, None, NotGiven] = NOT_GIVEN,
        request_options: Optional[RequestOptions] = None,
    ) -> Group:
        """Create a group

        Create a new group within an organization.

        Args:
            organization_id: The ID of the organization.
            name: The name of the Group.
            description: An optional description of the Group.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            Group

        Raises:
            BadRequestError: If the request is malformed (400).
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            UnprocessableEntityError: If the request data is unprocessable (422).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        body: Dict[str, Any] = {
            "name": name,
        }
        if not isinstance(description, NotGiven):
            body["description"] = description
        return self._client.request(
            method="post",
            path=("organizations", str(organization_id), "groups"),
            body=body,
            model=Group,
            request_options=request_options,
        )

    def get_organization_group(
        self,
        organization_id: str,
        group_id: str,
        *,
        request_options: Optional[RequestOptions] = None,
    ) -> Group:
        """Get a group

        Retrieve a group by its ID within an organization.

        Args:
            organization_id: The ID of the organization.
            group_id: The ID of the group.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            Group

        Raises:
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        return self._client.request(
            method="get",
            path=("organizations", str(organization_id), "groups", str(group_id)),
            model=Group,
            request_options=request_options,
        )

    def update_organization_group(
        self,
        organization_id: str,
        group_id: str,
        *,
        name: Optional[str] = None,
        description: Union[str, None, NotGiven] = NOT_GIVEN,
        request_options: Optional[RequestOptions] = None,
    ) -> Group:
        """Update a group

        Update an existing group. Only the fields provided in the request body will be updated.

        Args:
            organization_id: The ID of the organization.
            group_id: The ID of the group.
            name: The name of the Group.
            description: An optional description of the Group.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            Group

        Raises:
            BadRequestError: If the request is malformed (400).
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            UnprocessableEntityError: If the request data is unprocessable (422).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        body: Dict[str, Any] = {
            k: v
            for k, v in {
                "name": name,
            }.items()
            if v is not None
        }
        if not isinstance(description, NotGiven):
            body["description"] = description
        return self._client.request(
            method="patch",
            path=("organizations", str(organization_id), "groups", str(group_id)),
            body=body,
            model=Group,
            request_options=request_options,
        )

    def delete_organization_group(
        self,
        organization_id: str,
        group_id: str,
        *,
        request_options: Optional[RequestOptions] = None,
    ) -> None:
        """Delete a group

        Delete a group from an organization.

        Args:
            organization_id: The ID of the organization.
            group_id: The ID of the group.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Raises:
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        self._client.request(
            method="delete",
            path=("organizations", str(organization_id), "groups", str(group_id)),
            request_options=request_options,
        )

    def list_group_organization_memberships(
        self,
        organization_id: str,
        group_id: str,
        *,
        limit: Optional[int] = None,
        before: Optional[str] = None,
        after: Optional[str] = None,
        order: Optional[Union[PaginationOrder, str]] = "desc",
        request_options: Optional[RequestOptions] = None,
    ) -> SyncPage[UserOrganizationMembershipBaseListData]:
        """List Group members

        Get a list of organization memberships in a group.

        Args:
            organization_id: Unique identifier of the Organization.
            group_id: Unique identifier of the Group.
            limit: Upper limit on the number of objects to return, between `1` and `100`. Defaults to `10`.
            before: An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `before="obj_123"` to fetch a new batch of objects before `"obj_123"`.
            after: An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `after="obj_123"` to fetch a new batch of objects after `"obj_123"`.
            order: Order the results by the creation time. Supported values are `"asc"` (ascending), `"desc"` (descending), and `"normal"` (descending with reversed cursor semantics where `before` fetches older records and `after` fetches newer records). Defaults to `desc`.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            SyncPage[UserOrganizationMembershipBaseListData]

        Raises:
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        params = {
            k: v
            for k, v in {
                "limit": limit,
                "before": before,
                "after": after,
                "order": enum_value(order) if order is not None else None,
            }.items()
            if v is not None
        }
        return self._client.request_page(
            method="get",
            path=(
                "organizations",
                str(organization_id),
                "groups",
                str(group_id),
                "organization-memberships",
            ),
            model=UserOrganizationMembershipBaseListData,
            params=params,
            request_options=request_options,
        )

    def create_group_organization_membership(
        self,
        organization_id: str,
        group_id: str,
        *,
        organization_membership_id: str,
        request_options: Optional[RequestOptions] = None,
    ) -> Group:
        """Add a member to a Group

        Add an organization membership to a group.

        Args:
            organization_id: Unique identifier of the Organization.
            group_id: Unique identifier of the Group.
            organization_membership_id: The ID of the Organization Membership to add to the group.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            Group

        Raises:
            BadRequestError: If the request is malformed (400).
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            UnprocessableEntityError: If the request data is unprocessable (422).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        body: Dict[str, Any] = {
            "organization_membership_id": organization_membership_id,
        }
        return self._client.request(
            method="post",
            path=(
                "organizations",
                str(organization_id),
                "groups",
                str(group_id),
                "organization-memberships",
            ),
            body=body,
            model=Group,
            request_options=request_options,
        )

    def delete_group_organization_membership(
        self,
        organization_id: str,
        group_id: str,
        om_id: str,
        *,
        request_options: Optional[RequestOptions] = None,
    ) -> None:
        """Remove a member from a Group

        Remove an organization membership from a group.

        Args:
            organization_id: Unique identifier of the Organization.
            group_id: Unique identifier of the Group.
            om_id: Unique identifier of the Organization Membership.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Raises:
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        self._client.request(
            method="delete",
            path=(
                "organizations",
                str(organization_id),
                "groups",
                str(group_id),
                "organization-memberships",
                str(om_id),
            ),
            request_options=request_options,
        )


class AsyncGroups:
    """Groups API resources (async)."""

    def __init__(self, client: "AsyncWorkOSClient") -> None:
        self._client = client

    async def list_organization_groups(
        self,
        organization_id: str,
        *,
        limit: Optional[int] = None,
        before: Optional[str] = None,
        after: Optional[str] = None,
        order: Optional[Union[PaginationOrder, str]] = "desc",
        request_options: Optional[RequestOptions] = None,
    ) -> AsyncPage[Group]:
        """List groups

        Get a paginated list of groups within an organization.

        Args:
            organization_id: The ID of the organization.
            limit: Upper limit on the number of objects to return, between `1` and `100`. Defaults to `10`.
            before: An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `before="obj_123"` to fetch a new batch of objects before `"obj_123"`.
            after: An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `after="obj_123"` to fetch a new batch of objects after `"obj_123"`.
            order: Order the results by the creation time. Supported values are `"asc"` (ascending), `"desc"` (descending), and `"normal"` (descending with reversed cursor semantics where `before` fetches older records and `after` fetches newer records). Defaults to `desc`.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            AsyncPage[Group]

        Raises:
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        params = {
            k: v
            for k, v in {
                "limit": limit,
                "before": before,
                "after": after,
                "order": enum_value(order) if order is not None else None,
            }.items()
            if v is not None
        }
        return await self._client.request_page(
            method="get",
            path=("organizations", str(organization_id), "groups"),
            model=Group,
            params=params,
            request_options=request_options,
        )

    async def create_organization_group(
        self,
        organization_id: str,
        *,
        name: str,
        description: Union[str, None, NotGiven] = NOT_GIVEN,
        request_options: Optional[RequestOptions] = None,
    ) -> Group:
        """Create a group

        Create a new group within an organization.

        Args:
            organization_id: The ID of the organization.
            name: The name of the Group.
            description: An optional description of the Group.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            Group

        Raises:
            BadRequestError: If the request is malformed (400).
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            UnprocessableEntityError: If the request data is unprocessable (422).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        body: Dict[str, Any] = {
            "name": name,
        }
        if not isinstance(description, NotGiven):
            body["description"] = description
        return await self._client.request(
            method="post",
            path=("organizations", str(organization_id), "groups"),
            body=body,
            model=Group,
            request_options=request_options,
        )

    async def get_organization_group(
        self,
        organization_id: str,
        group_id: str,
        *,
        request_options: Optional[RequestOptions] = None,
    ) -> Group:
        """Get a group

        Retrieve a group by its ID within an organization.

        Args:
            organization_id: The ID of the organization.
            group_id: The ID of the group.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            Group

        Raises:
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        return await self._client.request(
            method="get",
            path=("organizations", str(organization_id), "groups", str(group_id)),
            model=Group,
            request_options=request_options,
        )

    async def update_organization_group(
        self,
        organization_id: str,
        group_id: str,
        *,
        name: Optional[str] = None,
        description: Union[str, None, NotGiven] = NOT_GIVEN,
        request_options: Optional[RequestOptions] = None,
    ) -> Group:
        """Update a group

        Update an existing group. Only the fields provided in the request body will be updated.

        Args:
            organization_id: The ID of the organization.
            group_id: The ID of the group.
            name: The name of the Group.
            description: An optional description of the Group.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            Group

        Raises:
            BadRequestError: If the request is malformed (400).
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            UnprocessableEntityError: If the request data is unprocessable (422).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        body: Dict[str, Any] = {
            k: v
            for k, v in {
                "name": name,
            }.items()
            if v is not None
        }
        if not isinstance(description, NotGiven):
            body["description"] = description
        return await self._client.request(
            method="patch",
            path=("organizations", str(organization_id), "groups", str(group_id)),
            body=body,
            model=Group,
            request_options=request_options,
        )

    async def delete_organization_group(
        self,
        organization_id: str,
        group_id: str,
        *,
        request_options: Optional[RequestOptions] = None,
    ) -> None:
        """Delete a group

        Delete a group from an organization.

        Args:
            organization_id: The ID of the organization.
            group_id: The ID of the group.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Raises:
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        await self._client.request(
            method="delete",
            path=("organizations", str(organization_id), "groups", str(group_id)),
            request_options=request_options,
        )

    async def list_group_organization_memberships(
        self,
        organization_id: str,
        group_id: str,
        *,
        limit: Optional[int] = None,
        before: Optional[str] = None,
        after: Optional[str] = None,
        order: Optional[Union[PaginationOrder, str]] = "desc",
        request_options: Optional[RequestOptions] = None,
    ) -> AsyncPage[UserOrganizationMembershipBaseListData]:
        """List Group members

        Get a list of organization memberships in a group.

        Args:
            organization_id: Unique identifier of the Organization.
            group_id: Unique identifier of the Group.
            limit: Upper limit on the number of objects to return, between `1` and `100`. Defaults to `10`.
            before: An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `before="obj_123"` to fetch a new batch of objects before `"obj_123"`.
            after: An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `after="obj_123"` to fetch a new batch of objects after `"obj_123"`.
            order: Order the results by the creation time. Supported values are `"asc"` (ascending), `"desc"` (descending), and `"normal"` (descending with reversed cursor semantics where `before` fetches older records and `after` fetches newer records). Defaults to `desc`.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            AsyncPage[UserOrganizationMembershipBaseListData]

        Raises:
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        params = {
            k: v
            for k, v in {
                "limit": limit,
                "before": before,
                "after": after,
                "order": enum_value(order) if order is not None else None,
            }.items()
            if v is not None
        }
        return await self._client.request_page(
            method="get",
            path=(
                "organizations",
                str(organization_id),
                "groups",
                str(group_id),
                "organization-memberships",
            ),
            model=UserOrganizationMembershipBaseListData,
            params=params,
            request_options=request_options,
        )

    async def create_group_organization_membership(
        self,
        organization_id: str,
        group_id: str,
        *,
        organization_membership_id: str,
        request_options: Optional[RequestOptions] = None,
    ) -> Group:
        """Add a member to a Group

        Add an organization membership to a group.

        Args:
            organization_id: Unique identifier of the Organization.
            group_id: Unique identifier of the Group.
            organization_membership_id: The ID of the Organization Membership to add to the group.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Returns:
            Group

        Raises:
            BadRequestError: If the request is malformed (400).
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            UnprocessableEntityError: If the request data is unprocessable (422).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        body: Dict[str, Any] = {
            "organization_membership_id": organization_membership_id,
        }
        return await self._client.request(
            method="post",
            path=(
                "organizations",
                str(organization_id),
                "groups",
                str(group_id),
                "organization-memberships",
            ),
            body=body,
            model=Group,
            request_options=request_options,
        )

    async def delete_group_organization_membership(
        self,
        organization_id: str,
        group_id: str,
        om_id: str,
        *,
        request_options: Optional[RequestOptions] = None,
    ) -> None:
        """Remove a member from a Group

        Remove an organization membership from a group.

        Args:
            organization_id: Unique identifier of the Organization.
            group_id: Unique identifier of the Group.
            om_id: Unique identifier of the Organization Membership.
            request_options: Per-request options. Supports extra_headers, timeout, max_retries, and base_url override.

        Raises:
            AuthorizationError: If the request is forbidden (403).
            NotFoundError: If the resource is not found (404).
            AuthenticationError: If the API key is invalid (401).
            RateLimitExceededError: If rate limited (429).
            ServerError: If the server returns a 5xx error.
        """
        await self._client.request(
            method="delete",
            path=(
                "organizations",
                str(organization_id),
                "groups",
                str(group_id),
                "organization-memberships",
                str(om_id),
            ),
            request_options=request_options,
        )
