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

import typing
from ..core.client_wrapper import SyncClientWrapper
from .raw_client import RawOAuthClient
from ..core.request_options import RequestOptions
from ..types.revoke_token_response import RevokeTokenResponse
from ..types.obtain_token_response import ObtainTokenResponse
from ..types.retrieve_token_status_response import RetrieveTokenStatusResponse
from ..core.client_wrapper import AsyncClientWrapper
from .raw_client import AsyncRawOAuthClient

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


class OAuthClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawOAuthClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        RawOAuthClient
        """
        return self._raw_client

    def revoke_token(
        self,
        *,
        client_id: typing.Optional[str] = OMIT,
        access_token: typing.Optional[str] = OMIT,
        merchant_id: typing.Optional[str] = OMIT,
        revoke_only_access_token: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> RevokeTokenResponse:
        """
        Revokes an access token generated with the OAuth flow.

        If an account has more than one OAuth access token for your application, this
        endpoint revokes all of them, regardless of which token you specify.

        __Important:__ The `Authorization` header for this endpoint must have the
        following format:

        ```
        Authorization: Client APPLICATION_SECRET
        ```

        Replace `APPLICATION_SECRET` with the application secret on the **OAuth**
        page for your application in the Developer Dashboard.

        Parameters
        ----------
        client_id : typing.Optional[str]
            The Square-issued ID for your application, which is available on the **OAuth** page in the
            [Developer Dashboard](https://developer.squareup.com/apps).

        access_token : typing.Optional[str]
            The access token of the merchant whose token you want to revoke.
            Do not provide a value for `merchant_id` if you provide this parameter.

        merchant_id : typing.Optional[str]
            The ID of the merchant whose token you want to revoke.
            Do not provide a value for `access_token` if you provide this parameter.

        revoke_only_access_token : typing.Optional[bool]
            If `true`, terminate the given single access token, but do not
            terminate the entire authorization.
            Default: `false`

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

        Returns
        -------
        RevokeTokenResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.o_auth.revoke_token(
            client_id="CLIENT_ID",
            access_token="ACCESS_TOKEN",
        )
        """
        response = self._raw_client.revoke_token(
            client_id=client_id,
            access_token=access_token,
            merchant_id=merchant_id,
            revoke_only_access_token=revoke_only_access_token,
            request_options=request_options,
        )
        return response.data

    def obtain_token(
        self,
        *,
        client_id: str,
        grant_type: str,
        client_secret: typing.Optional[str] = OMIT,
        code: typing.Optional[str] = OMIT,
        redirect_uri: typing.Optional[str] = OMIT,
        refresh_token: typing.Optional[str] = OMIT,
        migration_token: typing.Optional[str] = OMIT,
        scopes: typing.Optional[typing.Sequence[str]] = OMIT,
        short_lived: typing.Optional[bool] = OMIT,
        code_verifier: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ObtainTokenResponse:
        """
        Returns an OAuth access token and refresh token using the `authorization_code`
        or `refresh_token` grant type.

        When `grant_type` is `authorization_code`:
        - With the [code flow](https://developer.squareup.com/docs/oauth-api/overview#code-flow),
        provide `code`, `client_id`, and `client_secret`.
        - With the [PKCE flow](https://developer.squareup.com/docs/oauth-api/overview#pkce-flow),
        provide `code`, `client_id`, and `code_verifier`.

        When `grant_type` is `refresh_token`:
        - With the code flow, provide `refresh_token`, `client_id`, and `client_secret`.
        The response returns the same refresh token provided in the request.
        - With the PKCE flow, provide `refresh_token` and `client_id`. The response returns
        a new refresh token.

        You can use the `scopes` parameter to limit the set of permissions authorized by the
        access token. You can use the `short_lived` parameter to create an access token that
        expires in 24 hours.

        __Important:__ OAuth tokens should be encrypted and stored on a secure server.
        Application clients should never interact directly with OAuth tokens.

        Parameters
        ----------
        client_id : str
            The Square-issued ID of your application, which is available as the **Application ID**
            on the **OAuth** page in the [Developer Console](https://developer.squareup.com/apps).

            Required for the code flow and PKCE flow for any grant type.

        grant_type : str
            The method used to obtain an OAuth access token. The request must include the
            credential that corresponds to the specified grant type. Valid values are:
            - `authorization_code` - Requires the `code` field.
            - `refresh_token` - Requires the `refresh_token` field.
            - `migration_token` - LEGACY for access tokens obtained using a Square API version prior
            to 2019-03-13. Requires the `migration_token` field.

        client_secret : typing.Optional[str]
            The secret key for your application, which is available as the **Application secret**
            on the **OAuth** page in the [Developer Console](https://developer.squareup.com/apps).

            Required for the code flow for any grant type. Don't confuse your client secret with your
            personal access token.

        code : typing.Optional[str]
            The authorization code to exchange for an OAuth access token. This is the `code`
            value that Square sent to your redirect URL in the authorization response.

            Required for the code flow and PKCE flow if `grant_type` is `authorization_code`.

        redirect_uri : typing.Optional[str]
            The redirect URL for your application, which you registered as the **Redirect URL**
            on the **OAuth** page in the [Developer Console](https://developer.squareup.com/apps).

            Required for the code flow and PKCE flow if `grant_type` is `authorization_code` and
            you provided the `redirect_uri` parameter in your authorization URL.

        refresh_token : typing.Optional[str]
            A valid refresh token used to generate a new OAuth access token. This is a
            refresh token that was returned in a previous `ObtainToken` response.

            Required for the code flow and PKCE flow if `grant_type` is `refresh_token`.

        migration_token : typing.Optional[str]
            __LEGACY__ A valid access token (obtained using a Square API version prior to 2019-03-13)
            used to generate a new OAuth access token.

            Required if `grant_type` is `migration_token`. For more information, see
            [Migrate to Using Refresh Tokens](https://developer.squareup.com/docs/oauth-api/migrate-to-refresh-tokens).

        scopes : typing.Optional[typing.Sequence[str]]
            The list of permissions that are explicitly requested for the access token.
            For example, ["MERCHANT_PROFILE_READ","PAYMENTS_READ","BANK_ACCOUNTS_READ"].

            The returned access token is limited to the permissions that are the intersection
            of these requested permissions and those authorized by the provided `refresh_token`.

            Optional for the code flow and PKCE flow if `grant_type` is `refresh_token`.

        short_lived : typing.Optional[bool]
            Indicates whether the returned access token should expire in 24 hours.

            Optional for the code flow and PKCE flow for any grant type. The default value is `false`.

        code_verifier : typing.Optional[str]
            The secret your application generated for the authorization request used to
            obtain the authorization code. This is the source of the `code_challenge` hash you
            provided in your authorization URL.

            Required for the PKCE flow if `grant_type` is `authorization_code`.

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

        Returns
        -------
        ObtainTokenResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.o_auth.obtain_token(
            client_id="sq0idp-uaPHILoPzWZk3tlJqlML0g",
            client_secret="sq0csp-30a-4C_tVOnTh14Piza2BfTPBXyLafLPWSzY1qAjeBfM",
            code="sq0cgb-l0SBqxs4uwxErTVyYOdemg",
            grant_type="authorization_code",
        )
        """
        response = self._raw_client.obtain_token(
            client_id=client_id,
            grant_type=grant_type,
            client_secret=client_secret,
            code=code,
            redirect_uri=redirect_uri,
            refresh_token=refresh_token,
            migration_token=migration_token,
            scopes=scopes,
            short_lived=short_lived,
            code_verifier=code_verifier,
            request_options=request_options,
        )
        return response.data

    def retrieve_token_status(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> RetrieveTokenStatusResponse:
        """
        Returns information about an [OAuth access token](https://developer.squareup.com/docs/build-basics/access-tokens#get-an-oauth-access-token) or an application’s [personal access token](https://developer.squareup.com/docs/build-basics/access-tokens#get-a-personal-access-token).

        Add the access token to the Authorization header of the request.

        __Important:__ The `Authorization` header you provide to this endpoint must have the following format:

        ```
        Authorization: Bearer ACCESS_TOKEN
        ```

        where `ACCESS_TOKEN` is a
        [valid production authorization credential](https://developer.squareup.com/docs/build-basics/access-tokens).

        If the access token is expired or not a valid access token, the endpoint returns an `UNAUTHORIZED` error.

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

        Returns
        -------
        RetrieveTokenStatusResponse
            Success

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.o_auth.retrieve_token_status()
        """
        response = self._raw_client.retrieve_token_status(request_options=request_options)
        return response.data

    def authorize(self, *, request_options: typing.Optional[RequestOptions] = None) -> None:
        """
        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        None

        Examples
        --------
        from square import Square

        client = Square(
            token="YOUR_TOKEN",
        )
        client.o_auth.authorize()
        """
        response = self._raw_client.authorize(request_options=request_options)
        return response.data


class AsyncOAuthClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawOAuthClient(client_wrapper=client_wrapper)

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

        Returns
        -------
        AsyncRawOAuthClient
        """
        return self._raw_client

    async def revoke_token(
        self,
        *,
        client_id: typing.Optional[str] = OMIT,
        access_token: typing.Optional[str] = OMIT,
        merchant_id: typing.Optional[str] = OMIT,
        revoke_only_access_token: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> RevokeTokenResponse:
        """
        Revokes an access token generated with the OAuth flow.

        If an account has more than one OAuth access token for your application, this
        endpoint revokes all of them, regardless of which token you specify.

        __Important:__ The `Authorization` header for this endpoint must have the
        following format:

        ```
        Authorization: Client APPLICATION_SECRET
        ```

        Replace `APPLICATION_SECRET` with the application secret on the **OAuth**
        page for your application in the Developer Dashboard.

        Parameters
        ----------
        client_id : typing.Optional[str]
            The Square-issued ID for your application, which is available on the **OAuth** page in the
            [Developer Dashboard](https://developer.squareup.com/apps).

        access_token : typing.Optional[str]
            The access token of the merchant whose token you want to revoke.
            Do not provide a value for `merchant_id` if you provide this parameter.

        merchant_id : typing.Optional[str]
            The ID of the merchant whose token you want to revoke.
            Do not provide a value for `access_token` if you provide this parameter.

        revoke_only_access_token : typing.Optional[bool]
            If `true`, terminate the given single access token, but do not
            terminate the entire authorization.
            Default: `false`

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

        Returns
        -------
        RevokeTokenResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.o_auth.revoke_token(
                client_id="CLIENT_ID",
                access_token="ACCESS_TOKEN",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.revoke_token(
            client_id=client_id,
            access_token=access_token,
            merchant_id=merchant_id,
            revoke_only_access_token=revoke_only_access_token,
            request_options=request_options,
        )
        return response.data

    async def obtain_token(
        self,
        *,
        client_id: str,
        grant_type: str,
        client_secret: typing.Optional[str] = OMIT,
        code: typing.Optional[str] = OMIT,
        redirect_uri: typing.Optional[str] = OMIT,
        refresh_token: typing.Optional[str] = OMIT,
        migration_token: typing.Optional[str] = OMIT,
        scopes: typing.Optional[typing.Sequence[str]] = OMIT,
        short_lived: typing.Optional[bool] = OMIT,
        code_verifier: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ObtainTokenResponse:
        """
        Returns an OAuth access token and refresh token using the `authorization_code`
        or `refresh_token` grant type.

        When `grant_type` is `authorization_code`:
        - With the [code flow](https://developer.squareup.com/docs/oauth-api/overview#code-flow),
        provide `code`, `client_id`, and `client_secret`.
        - With the [PKCE flow](https://developer.squareup.com/docs/oauth-api/overview#pkce-flow),
        provide `code`, `client_id`, and `code_verifier`.

        When `grant_type` is `refresh_token`:
        - With the code flow, provide `refresh_token`, `client_id`, and `client_secret`.
        The response returns the same refresh token provided in the request.
        - With the PKCE flow, provide `refresh_token` and `client_id`. The response returns
        a new refresh token.

        You can use the `scopes` parameter to limit the set of permissions authorized by the
        access token. You can use the `short_lived` parameter to create an access token that
        expires in 24 hours.

        __Important:__ OAuth tokens should be encrypted and stored on a secure server.
        Application clients should never interact directly with OAuth tokens.

        Parameters
        ----------
        client_id : str
            The Square-issued ID of your application, which is available as the **Application ID**
            on the **OAuth** page in the [Developer Console](https://developer.squareup.com/apps).

            Required for the code flow and PKCE flow for any grant type.

        grant_type : str
            The method used to obtain an OAuth access token. The request must include the
            credential that corresponds to the specified grant type. Valid values are:
            - `authorization_code` - Requires the `code` field.
            - `refresh_token` - Requires the `refresh_token` field.
            - `migration_token` - LEGACY for access tokens obtained using a Square API version prior
            to 2019-03-13. Requires the `migration_token` field.

        client_secret : typing.Optional[str]
            The secret key for your application, which is available as the **Application secret**
            on the **OAuth** page in the [Developer Console](https://developer.squareup.com/apps).

            Required for the code flow for any grant type. Don't confuse your client secret with your
            personal access token.

        code : typing.Optional[str]
            The authorization code to exchange for an OAuth access token. This is the `code`
            value that Square sent to your redirect URL in the authorization response.

            Required for the code flow and PKCE flow if `grant_type` is `authorization_code`.

        redirect_uri : typing.Optional[str]
            The redirect URL for your application, which you registered as the **Redirect URL**
            on the **OAuth** page in the [Developer Console](https://developer.squareup.com/apps).

            Required for the code flow and PKCE flow if `grant_type` is `authorization_code` and
            you provided the `redirect_uri` parameter in your authorization URL.

        refresh_token : typing.Optional[str]
            A valid refresh token used to generate a new OAuth access token. This is a
            refresh token that was returned in a previous `ObtainToken` response.

            Required for the code flow and PKCE flow if `grant_type` is `refresh_token`.

        migration_token : typing.Optional[str]
            __LEGACY__ A valid access token (obtained using a Square API version prior to 2019-03-13)
            used to generate a new OAuth access token.

            Required if `grant_type` is `migration_token`. For more information, see
            [Migrate to Using Refresh Tokens](https://developer.squareup.com/docs/oauth-api/migrate-to-refresh-tokens).

        scopes : typing.Optional[typing.Sequence[str]]
            The list of permissions that are explicitly requested for the access token.
            For example, ["MERCHANT_PROFILE_READ","PAYMENTS_READ","BANK_ACCOUNTS_READ"].

            The returned access token is limited to the permissions that are the intersection
            of these requested permissions and those authorized by the provided `refresh_token`.

            Optional for the code flow and PKCE flow if `grant_type` is `refresh_token`.

        short_lived : typing.Optional[bool]
            Indicates whether the returned access token should expire in 24 hours.

            Optional for the code flow and PKCE flow for any grant type. The default value is `false`.

        code_verifier : typing.Optional[str]
            The secret your application generated for the authorization request used to
            obtain the authorization code. This is the source of the `code_challenge` hash you
            provided in your authorization URL.

            Required for the PKCE flow if `grant_type` is `authorization_code`.

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

        Returns
        -------
        ObtainTokenResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.o_auth.obtain_token(
                client_id="sq0idp-uaPHILoPzWZk3tlJqlML0g",
                client_secret="sq0csp-30a-4C_tVOnTh14Piza2BfTPBXyLafLPWSzY1qAjeBfM",
                code="sq0cgb-l0SBqxs4uwxErTVyYOdemg",
                grant_type="authorization_code",
            )


        asyncio.run(main())
        """
        response = await self._raw_client.obtain_token(
            client_id=client_id,
            grant_type=grant_type,
            client_secret=client_secret,
            code=code,
            redirect_uri=redirect_uri,
            refresh_token=refresh_token,
            migration_token=migration_token,
            scopes=scopes,
            short_lived=short_lived,
            code_verifier=code_verifier,
            request_options=request_options,
        )
        return response.data

    async def retrieve_token_status(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> RetrieveTokenStatusResponse:
        """
        Returns information about an [OAuth access token](https://developer.squareup.com/docs/build-basics/access-tokens#get-an-oauth-access-token) or an application’s [personal access token](https://developer.squareup.com/docs/build-basics/access-tokens#get-a-personal-access-token).

        Add the access token to the Authorization header of the request.

        __Important:__ The `Authorization` header you provide to this endpoint must have the following format:

        ```
        Authorization: Bearer ACCESS_TOKEN
        ```

        where `ACCESS_TOKEN` is a
        [valid production authorization credential](https://developer.squareup.com/docs/build-basics/access-tokens).

        If the access token is expired or not a valid access token, the endpoint returns an `UNAUTHORIZED` error.

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

        Returns
        -------
        RetrieveTokenStatusResponse
            Success

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.o_auth.retrieve_token_status()


        asyncio.run(main())
        """
        response = await self._raw_client.retrieve_token_status(request_options=request_options)
        return response.data

    async def authorize(self, *, request_options: typing.Optional[RequestOptions] = None) -> None:
        """
        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from square import AsyncSquare

        client = AsyncSquare(
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.o_auth.authorize()


        asyncio.run(main())
        """
        response = await self._raw_client.authorize(request_options=request_options)
        return response.data
