# 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_user_identity_response_content import DeleteUserIdentityResponseContent
from ...types.user_id import UserId
from ...types.user_identity import UserIdentity
from ...types.user_identity_provider_enum import UserIdentityProviderEnum
from .raw_client import AsyncRawIdentitiesClient, RawIdentitiesClient

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


class IdentitiesClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawIdentitiesClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        RawIdentitiesClient
        """
        return self._raw_client

    def link(
        self,
        id: str,
        *,
        provider: typing.Optional[UserIdentityProviderEnum] = OMIT,
        connection_id: typing.Optional[str] = OMIT,
        user_id: typing.Optional[UserId] = OMIT,
        link_with: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.List[UserIdentity]:
        """
        Link two user accounts together forming a primary and secondary relationship. On successful linking, the endpoint returns the new array of the primary account identities.

        Note: There are two ways of invoking the endpoint:

        - With the authenticated primary account's JWT in the Authorization header, which has the `update:current_user_identities` scope:

          ```http
          POST /api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities
          Authorization: "Bearer PRIMARY_ACCOUNT_JWT"
          {
            "link_with": "SECONDARY_ACCOUNT_JWT"
          }
          ```

          In this case, only the `link_with` param is required in the body, which also contains the JWT obtained upon the secondary account's authentication.

        - With a token generated by the API V2 containing the `update:users` scope:

          ```http
          POST /api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities
          Authorization: "Bearer YOUR_API_V2_TOKEN"
          {
            "provider": "SECONDARY_ACCOUNT_PROVIDER",
            "connection_id": "SECONDARY_ACCOUNT_CONNECTION_ID(OPTIONAL)",
            "user_id": "SECONDARY_ACCOUNT_USER_ID"
          }
          ```

          In this case you need to send `provider` and `user_id` in the body. Optionally you can also send the `connection_id` param which is suitable for identifying a particular database connection for the 'auth0' provider.

        Parameters
        ----------
        id : str
            ID of the primary user account to link a second user account to.

        provider : typing.Optional[UserIdentityProviderEnum]
            Identity provider of the secondary user account being linked.

        connection_id : typing.Optional[str]
            connection_id of the secondary user account being linked when more than one `auth0` database provider exists.

        user_id : typing.Optional[UserId]
            user_id of the secondary user account being linked.

        link_with : typing.Optional[str]
            JWT for the secondary account being linked. If sending this parameter, `provider`, `user_id`, and `connection_id` must not be sent.

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

        Returns
        -------
        typing.List[UserIdentity]
            Identity successfully added.

        Examples
        --------
        from auth0 import Auth0

        client = Auth0(
            token="YOUR_TOKEN",
        )
        client.users.identities.link(
            id="id",
        )
        """
        _response = self._raw_client.link(
            id,
            provider=provider,
            connection_id=connection_id,
            user_id=user_id,
            link_with=link_with,
            request_options=request_options,
        )
        return _response.data

    def delete(
        self,
        id: str,
        provider: UserIdentityProviderEnum,
        user_id: str,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> DeleteUserIdentityResponseContent:
        """
        Unlink a specific secondary account from a target user. This action requires the ID of both the target user and the secondary account.

        Unlinking the secondary account removes it from the identities array of the target user and creates a new standalone profile for the secondary account. To learn more, review [Unlink User Accounts](https://auth0.com/docs/manage-users/user-accounts/user-account-linking/unlink-user-accounts).

        Parameters
        ----------
        id : str
            ID of the primary user account.

        provider : UserIdentityProviderEnum
            Identity provider name of the secondary linked account (e.g. `google-oauth2`).

        user_id : str
            ID of the secondary linked account (e.g. `123456789081523216417` part after the `|` in `google-oauth2|123456789081523216417`).

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

        Returns
        -------
        DeleteUserIdentityResponseContent
            User identity successfully unlinked.

        Examples
        --------
        from auth0 import Auth0

        client = Auth0(
            token="YOUR_TOKEN",
        )
        client.users.identities.delete(
            id="id",
            provider="ad",
            user_id="user_id",
        )
        """
        _response = self._raw_client.delete(id, provider, user_id, request_options=request_options)
        return _response.data


class AsyncIdentitiesClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawIdentitiesClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        AsyncRawIdentitiesClient
        """
        return self._raw_client

    async def link(
        self,
        id: str,
        *,
        provider: typing.Optional[UserIdentityProviderEnum] = OMIT,
        connection_id: typing.Optional[str] = OMIT,
        user_id: typing.Optional[UserId] = OMIT,
        link_with: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.List[UserIdentity]:
        """
        Link two user accounts together forming a primary and secondary relationship. On successful linking, the endpoint returns the new array of the primary account identities.

        Note: There are two ways of invoking the endpoint:

        - With the authenticated primary account's JWT in the Authorization header, which has the `update:current_user_identities` scope:

          ```http
          POST /api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities
          Authorization: "Bearer PRIMARY_ACCOUNT_JWT"
          {
            "link_with": "SECONDARY_ACCOUNT_JWT"
          }
          ```

          In this case, only the `link_with` param is required in the body, which also contains the JWT obtained upon the secondary account's authentication.

        - With a token generated by the API V2 containing the `update:users` scope:

          ```http
          POST /api/v2/users/PRIMARY_ACCOUNT_USER_ID/identities
          Authorization: "Bearer YOUR_API_V2_TOKEN"
          {
            "provider": "SECONDARY_ACCOUNT_PROVIDER",
            "connection_id": "SECONDARY_ACCOUNT_CONNECTION_ID(OPTIONAL)",
            "user_id": "SECONDARY_ACCOUNT_USER_ID"
          }
          ```

          In this case you need to send `provider` and `user_id` in the body. Optionally you can also send the `connection_id` param which is suitable for identifying a particular database connection for the 'auth0' provider.

        Parameters
        ----------
        id : str
            ID of the primary user account to link a second user account to.

        provider : typing.Optional[UserIdentityProviderEnum]
            Identity provider of the secondary user account being linked.

        connection_id : typing.Optional[str]
            connection_id of the secondary user account being linked when more than one `auth0` database provider exists.

        user_id : typing.Optional[UserId]
            user_id of the secondary user account being linked.

        link_with : typing.Optional[str]
            JWT for the secondary account being linked. If sending this parameter, `provider`, `user_id`, and `connection_id` must not be sent.

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

        Returns
        -------
        typing.List[UserIdentity]
            Identity successfully added.

        Examples
        --------
        import asyncio

        from auth0 import AsyncAuth0

        client = AsyncAuth0(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.users.identities.link(
                id="id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.link(
            id,
            provider=provider,
            connection_id=connection_id,
            user_id=user_id,
            link_with=link_with,
            request_options=request_options,
        )
        return _response.data

    async def delete(
        self,
        id: str,
        provider: UserIdentityProviderEnum,
        user_id: str,
        *,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> DeleteUserIdentityResponseContent:
        """
        Unlink a specific secondary account from a target user. This action requires the ID of both the target user and the secondary account.

        Unlinking the secondary account removes it from the identities array of the target user and creates a new standalone profile for the secondary account. To learn more, review [Unlink User Accounts](https://auth0.com/docs/manage-users/user-accounts/user-account-linking/unlink-user-accounts).

        Parameters
        ----------
        id : str
            ID of the primary user account.

        provider : UserIdentityProviderEnum
            Identity provider name of the secondary linked account (e.g. `google-oauth2`).

        user_id : str
            ID of the secondary linked account (e.g. `123456789081523216417` part after the `|` in `google-oauth2|123456789081523216417`).

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

        Returns
        -------
        DeleteUserIdentityResponseContent
            User identity successfully unlinked.

        Examples
        --------
        import asyncio

        from auth0 import AsyncAuth0

        client = AsyncAuth0(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.users.identities.delete(
                id="id",
                provider="ad",
                user_id="user_id",
            )


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