"""Microsoft Advertising OAuth adapter using Microsoft identity platform."""

import httpx


class MicrosoftAdsOAuthError(Exception):
    def __init__(self, code="provider_unavailable"):
        self.code = code
        super().__init__(code)


class MicrosoftAdsOAuthClient:
    async def token(self, **data):
        async with httpx.AsyncClient(timeout=20) as client:
            try:
                response = await client.post(
                    "https://login.microsoftonline.com/common/oauth2/v2.0/token", data=data
                )
                payload = response.json()
            except (httpx.HTTPError, ValueError):
                raise MicrosoftAdsOAuthError() from None
        if response.is_error:
            code = payload.get("error")
            raise MicrosoftAdsOAuthError(
                code if code in {"invalid_grant", "invalid_client"} else "provider_unavailable"
            )
        if not payload.get("access_token"):
            raise MicrosoftAdsOAuthError()
        return payload

    async def userinfo(self, token):
        async with httpx.AsyncClient(timeout=20) as client:
            try:
                response = await client.get(
                    "https://graph.microsoft.com/oidc/userinfo",
                    headers={"Authorization": f"Bearer {token['access_token']}"},
                )
                response.raise_for_status()
                payload = response.json()
            except (httpx.HTTPError, ValueError):
                raise MicrosoftAdsOAuthError() from None
        if not payload.get("sub"):
            raise MicrosoftAdsOAuthError("identity_not_verified")
        return {"sub": str(payload["sub"])}
