"""
A JupyterHub authenticator class for use with Azure AD as an identity provider.
"""

import os

import jwt
from jupyterhub.auth import LocalAuthenticator
from traitlets import Unicode, default

from .oauth2 import OAuthenticator


class AzureAdOAuthenticator(OAuthenticator):
    user_auth_state_key = "user"

    @default("login_service")
    def _login_service_default(self):
        return os.environ.get("LOGIN_SERVICE", "Azure AD")

    @default("username_claim")
    def _username_claim_default(self):
        return "name"

    user_groups_claim = Unicode(
        "",
        config=True,
        help="""
        .. deprecated:: 17.0

            Use :attr:`auth_state_groups_key` instead.
        """,
    )

    @default('auth_state_groups_key')
    def _auth_state_groups_key_default(self):
        key = "user.groups"
        if self.user_groups_claim:
            key = f"{self.user_auth_state_key}.{self.user_groups_claim}"
            cls = self.__class__.__name__
            self.log.warning(
                f"{cls}.user_groups_claim is deprecated in OAuthenticator 17. Use {cls}.auth_state_groups_key = {key!r}"
            )
        return key

    tenant_id = Unicode(
        config=True,
        help="""
        An Azure tenant ID for which an OAuth application is registered via
        `client_id` and `client_secret`.

        This is used to set the default values of `authorize_url` and
        `token_url`.
        """,
    )

    graph_url = Unicode(
        config=True,
        help="""
        An Azure graph url for which an OAuth application. This correlates
        to which cloud such as Azure portal (global service) [default] 
        Azure GOV, Azure China, etc. are being used.

        This is used to set the default values of `authorize_url` and
        `token_url`.
        """,
    )

    @default('tenant_id')
    def _tenant_id_default(self):
        return os.environ.get('AAD_TENANT_ID', '')

    @default('graph_url')
    def _graph_url_default(self):
        return 'https://login.microsoftonline.com'

    @default("authorize_url")
    def _authorize_url_default(self):
        return (
            f"{self.graph_url}/{self.tenant_id}/oauth2/authorize"
            if self.tenant_id
            else f"{self.graph_url}/oauth2/authorize"
        )

    @default("token_url")
    def _token_url_default(self):
        return (
            f"{self.graph_url}/{self.tenant_id}/oauth2/token"
            if self.tenant_id
            else f"{self.graph_url}/oauth2/token"
        )

    async def token_to_user(self, token_info):
        id_token = token_info['id_token']
        decoded = jwt.decode(
            id_token,
            options={"verify_signature": False},
            audience=self.client_id,
        )

        return decoded


class LocalAzureAdOAuthenticator(LocalAuthenticator, AzureAdOAuthenticator):
    """A version that mixes in local system user creation"""
