"""Configuration for gnexus-gauth client."""

from urllib.parse import urlparse

from gnexus_gauth.exceptions import ConfigurationException


class GAuthConfig:
    """Package configuration.

    Holds base URL, client credentials, redirect URI and endpoint paths.
    """

    def __init__(
        self,
        base_url: str,
        client_id: str,
        client_secret: str,
        redirect_uri: str,
        authorize_path: str = "/oauth/authorize",
        token_path: str = "/oauth/token",
        refresh_path: str = "/oauth/refresh",
        revoke_path: str = "/oauth/revoke",
        user_info_path: str = "/oauth/userinfo",
        state_ttl_seconds: int = 300,
        webhook_tolerance_seconds: int = 300,
        user_agent: str | None = None,
    ) -> None:
        base_url = base_url.rstrip("/")
        if not base_url:
            raise ConfigurationException("Invalid gnexus-auth base URL.")
        parsed = urlparse(base_url)
        if not parsed.scheme or not parsed.netloc:
            raise ConfigurationException("Invalid gnexus-auth base URL.")

        if not client_id:
            raise ConfigurationException("client_id must not be empty.")
        if not client_secret:
            raise ConfigurationException("client_secret must not be empty.")

        parsed_redirect = urlparse(redirect_uri)
        if not parsed_redirect.scheme or not parsed_redirect.netloc:
            raise ConfigurationException("Invalid redirect URI.")

        if state_ttl_seconds < 60:
            raise ConfigurationException("state TTL must be at least 60 seconds.")
        if webhook_tolerance_seconds < 0:
            raise ConfigurationException("webhook tolerance must be zero or greater.")

        self._base_url = base_url
        self._client_id = client_id
        self._client_secret = client_secret
        self._redirect_uri = redirect_uri
        self._authorize_path = authorize_path
        self._token_path = token_path
        self._refresh_path = refresh_path
        self._revoke_path = revoke_path
        self._user_info_path = user_info_path
        self._state_ttl_seconds = state_ttl_seconds
        self._webhook_tolerance_seconds = webhook_tolerance_seconds
        self._user_agent = user_agent

    @property
    def base_url(self) -> str:
        return self._base_url

    @property
    def client_id(self) -> str:
        return self._client_id

    @property
    def client_secret(self) -> str:
        return self._client_secret

    @property
    def redirect_uri(self) -> str:
        return self._redirect_uri

    @property
    def authorize_path(self) -> str:
        return self._authorize_path

    @property
    def token_path(self) -> str:
        return self._token_path

    @property
    def refresh_path(self) -> str:
        return self._refresh_path

    @property
    def revoke_path(self) -> str:
        return self._revoke_path

    @property
    def user_info_path(self) -> str:
        return self._user_info_path

    @property
    def state_ttl_seconds(self) -> int:
        return self._state_ttl_seconds

    @property
    def webhook_tolerance_seconds(self) -> int:
        return self._webhook_tolerance_seconds

    @property
    def user_agent(self) -> str | None:
        return self._user_agent

    @property
    def authorize_url(self) -> str:
        return self._base_url + self._authorize_path

    @property
    def token_url(self) -> str:
        return self._base_url + self._token_path

    @property
    def refresh_url(self) -> str:
        return self._base_url + self._refresh_path

    @property
    def revoke_url(self) -> str:
        return self._base_url + self._revoke_path

    @property
    def user_info_url(self) -> str:
        return self._base_url + self._user_info_path
