"""HubSpot OAuth adapter. Credentials and provider responses are never logged."""

import httpx


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


class HubSpotOAuthClient:
    async def token(self, **data):
        async with httpx.AsyncClient(timeout=20) as client:
            try:
                response = await client.post(
                    "https://api.hubapi.com/oauth/v1/token",
                    data={"grant_type": "authorization_code", **data},
                )
                payload = response.json()
            except (httpx.HTTPError, ValueError):
                raise HubSpotOAuthError() from None
        if response.is_error:
            code = payload.get("error")
            raise HubSpotOAuthError(
                code if code in {"invalid_grant", "invalid_client"} else "provider_unavailable"
            )
        if not payload.get("access_token"):
            raise HubSpotOAuthError()
        return payload

    async def userinfo(self, token):
        async with httpx.AsyncClient(timeout=20) as client:
            try:
                response = await client.get(
                    "https://api.hubapi.com/oauth/v1/access-tokens/"
                    + token["access_token"],
                )
                response.raise_for_status()
                payload = response.json()
            except (httpx.HTTPError, ValueError):
                raise HubSpotOAuthError() from None
        subject = payload.get("user_id") or payload.get("hub_id")
        if not subject:
            raise HubSpotOAuthError("identity_not_verified")
        return {"sub": str(subject), "portal_id": str(payload.get("hub_id", ""))}
